// Copyright (c) 2019 Emmanuel Gil Peyrot // // 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/. use xso::{FromXml, IntoXml}; use crate::ns; generate_element!( /// Source element for the ssrc SDP attribute. Source, "source", JINGLE_SSMA, attributes: [ /// Maps to the ssrc-id parameter. id: Required = "ssrc", ], children: [ /// List of attributes for this source. parameters: Vec = ("parameter", JINGLE_SSMA) => Parameter ] ); impl Source { /// Create a new SSMA Source element. pub fn new(id: u32) -> Source { Source { id, parameters: Vec::new(), } } } /// Parameter associated with a ssrc. #[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] #[xml(namespace = ns::JINGLE_SSMA, name = "parameter")] pub struct Parameter { /// The name of the parameter. #[xml(attribute)] pub name: String, /// The optional value of the parameter. #[xml(attribute(default))] pub value: Option, } 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", } ); generate_element!( /// Element grouping multiple ssrc. Group, "ssrc-group", JINGLE_SSMA, attributes: [ /// The semantics of this group. semantics: Required = "semantics", ], children: [ /// The various ssrc concerned by this group. sources: Vec = ("source", JINGLE_SSMA) => Source ] ); #[cfg(test)] mod tests { use super::*; use crate::Element; #[cfg(target_pointer_width = "32")] #[test] fn test_size() { assert_size!(Source, 16); assert_size!(Parameter, 24); assert_size!(Semantics, 1); assert_size!(Group, 16); } #[cfg(target_pointer_width = "64")] #[test] fn test_size() { assert_size!(Source, 32); assert_size!(Parameter, 48); assert_size!(Semantics, 1); assert_size!(Group, 32); } #[test] fn parse_source() { let elem: Element = " " .parse() .unwrap(); let mut ssrc = Source::try_from(elem).unwrap(); assert_eq!(ssrc.id, 1656081975); assert_eq!(ssrc.parameters.len(), 2); let parameter = ssrc.parameters.pop().unwrap(); assert_eq!(parameter.name, "msid"); assert_eq!( parameter.value.unwrap(), "MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIv MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIva0" ); let parameter = ssrc.parameters.pop().unwrap(); assert_eq!(parameter.name, "cname"); assert_eq!(parameter.value.unwrap(), "Yv/wvbCdsDW2Prgd"); } #[test] fn parse_source_group() { let elem: Element = " " .parse() .unwrap(); let mut group = Group::try_from(elem).unwrap(); assert_eq!(group.semantics, Semantics::Fid); assert_eq!(group.sources.len(), 2); let source = group.sources.pop().unwrap(); assert_eq!(source.id, 386328120); let source = group.sources.pop().unwrap(); assert_eq!(source.id, 2301230316); } }