jingle_ssma.rs

  1// Copyright (c) 2019 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
  2//
  3// This Source Code Form is subject to the terms of the Mozilla Public
  4// License, v. 2.0. If a copy of the MPL was not distributed with this
  5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6
  7use xso::{AsXml, FromXml};
  8
  9use crate::ns;
 10
 11/// Source element for the ssrc SDP attribute.
 12#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
 13#[xml(namespace = ns::JINGLE_SSMA, name = "source")]
 14pub struct Source {
 15    /// Maps to the ssrc-id parameter.
 16    #[xml(attribute = "ssrc")]
 17    pub id: u32,
 18
 19    /// List of attributes for this source.
 20    #[xml(child(n = ..))]
 21    pub parameters: Vec<Parameter>,
 22}
 23
 24impl Source {
 25    /// Create a new SSMA Source element.
 26    pub fn new(id: u32) -> Source {
 27        Source {
 28            id,
 29            parameters: Vec::new(),
 30        }
 31    }
 32}
 33
 34/// Parameter associated with a ssrc.
 35#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
 36#[xml(namespace = ns::JINGLE_SSMA, name = "parameter")]
 37pub struct Parameter {
 38    /// The name of the parameter.
 39    #[xml(attribute)]
 40    pub name: String,
 41
 42    /// The optional value of the parameter.
 43    #[xml(attribute(default))]
 44    pub value: Option<String>,
 45}
 46
 47generate_attribute!(
 48    /// From RFC5888, the list of allowed semantics.
 49    Semantics, "semantics", {
 50        /// Lip Synchronization, defined in RFC5888.
 51        Ls => "LS",
 52
 53        /// Flow Identification, defined in RFC5888.
 54        Fid => "FID",
 55
 56        /// Single Reservation Flow, defined in RFC3524.
 57        Srf => "SRF",
 58
 59        /// Alternative Network Address Types, defined in RFC4091.
 60        Anat => "ANAT",
 61
 62        /// Forward Error Correction, defined in RFC4756.
 63        Fec => "FEC",
 64
 65        /// Decoding Dependency, defined in RFC5583.
 66        Ddp => "DDP",
 67    }
 68);
 69
 70/// Element grouping multiple ssrc.
 71#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
 72#[xml(namespace = ns::JINGLE_SSMA, name = "ssrc-group")]
 73pub struct Group {
 74    /// The semantics of this group.
 75    #[xml(attribute)]
 76    pub semantics: Semantics,
 77
 78    /// The various ssrc concerned by this group.
 79    #[xml(child(n = ..))]
 80    pub sources: Vec<Source>,
 81}
 82
 83#[cfg(test)]
 84mod tests {
 85    use super::*;
 86    use minidom::Element;
 87
 88    #[cfg(target_pointer_width = "32")]
 89    #[test]
 90    fn test_size() {
 91        assert_size!(Source, 16);
 92        assert_size!(Parameter, 24);
 93        assert_size!(Semantics, 1);
 94        assert_size!(Group, 16);
 95    }
 96
 97    #[cfg(target_pointer_width = "64")]
 98    #[test]
 99    fn test_size() {
100        assert_size!(Source, 32);
101        assert_size!(Parameter, 48);
102        assert_size!(Semantics, 1);
103        assert_size!(Group, 32);
104    }
105
106    #[test]
107    fn parse_source() {
108        let elem: Element = "<source ssrc='1656081975' xmlns='urn:xmpp:jingle:apps:rtp:ssma:0'>
109    <parameter name='cname' value='Yv/wvbCdsDW2Prgd'/>
110    <parameter name='msid' value='MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIv MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIva0'/>
111</source>"
112                .parse()
113                .unwrap();
114        let mut ssrc = Source::try_from(elem).unwrap();
115        assert_eq!(ssrc.id, 1656081975);
116        assert_eq!(ssrc.parameters.len(), 2);
117        let parameter = ssrc.parameters.pop().unwrap();
118        assert_eq!(parameter.name, "msid");
119        assert_eq!(
120            parameter.value.unwrap(),
121            "MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIv MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIva0"
122        );
123        let parameter = ssrc.parameters.pop().unwrap();
124        assert_eq!(parameter.name, "cname");
125        assert_eq!(parameter.value.unwrap(), "Yv/wvbCdsDW2Prgd");
126    }
127
128    #[test]
129    fn parse_source_group() {
130        let elem: Element = "<ssrc-group semantics='FID' xmlns='urn:xmpp:jingle:apps:rtp:ssma:0'>
131    <source ssrc='2301230316'/>
132    <source ssrc='386328120'/>
133</ssrc-group>"
134            .parse()
135            .unwrap();
136        let mut group = Group::try_from(elem).unwrap();
137        assert_eq!(group.semantics, Semantics::Fid);
138        assert_eq!(group.sources.len(), 2);
139        let source = group.sources.pop().unwrap();
140        assert_eq!(source.id, 386328120);
141        let source = group.sources.pop().unwrap();
142        assert_eq!(source.id, 2301230316);
143    }
144}