jingle_rtp.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
  7generate_element!(
  8    /// Wrapper element describing an RTP session.
  9    Description, "description", JINGLE_RTP,
 10    attributes: [
 11        /// Namespace of the encryption scheme used.
 12        media: Required<String> = "media",
 13
 14        /// User-friendly name for the encryption scheme, should be `None` for OTR,
 15        /// legacy OpenPGP and OX.
 16        // XXX: is this a String or an u32?!  Refer to RFC 3550.
 17        ssrc: Option<String> = "ssrc",
 18    ],
 19    children: [
 20        /// List of encodings that can be used for this RTP stream.
 21        payload_types: Vec<PayloadType> = ("payload-type", JINGLE_RTP) => PayloadType
 22
 23        // TODO: Add support for <encryption/> and <bandwidth/>.
 24    ]
 25);
 26
 27generate_attribute!(
 28    /// The number of channels.
 29    Channels, "channels", u8, Default = 1
 30);
 31
 32generate_element!(
 33    /// An encoding that can be used for an RTP stream.
 34    PayloadType, "payload-type", JINGLE_RTP,
 35    attributes: [
 36        /// The number of channels.
 37        channels: Default<Channels> = "channels",
 38
 39        /// The sampling frequency in Hertz.
 40        clockrate: Option<u32> = "clockrate",
 41
 42        /// The payload identifier.
 43        id: Required<u8> = "id",
 44
 45        /// Maximum packet time as specified in RFC 4566.
 46        maxptime: Option<u32> = "maxptime",
 47
 48        /// The appropriate subtype of the MIME type.
 49        name: Option<String> = "name",
 50
 51        /// Packet time as specified in RFC 4566.
 52        ptime: Option<u32> = "ptime",
 53    ],
 54    children: [
 55        /// List of parameters specifying this payload-type.
 56        ///
 57        /// Their order MUST be ignored.
 58        parameters: Vec<Parameter> = ("parameter", JINGLE_RTP) => Parameter
 59    ]
 60);
 61
 62generate_element!(
 63    /// Parameter related to a payload.
 64    Parameter, "parameter", JINGLE_RTP,
 65    attributes: [
 66        /// The name of the parameter, from the list at
 67        /// https://www.iana.org/assignments/sdp-parameters/sdp-parameters.xhtml
 68        name: Required<String> = "name",
 69
 70        /// The value of this parameter.
 71        value: Required<String> = "value",
 72    ]
 73);
 74
 75#[cfg(test)]
 76mod tests {
 77    use super::*;
 78    use minidom::Element;
 79    use std::convert::TryFrom;
 80
 81    #[cfg(target_pointer_width = "32")]
 82    #[test]
 83    fn test_size() {
 84        assert_size!(Description, 36);
 85        assert_size!(Channels, 1);
 86        assert_size!(PayloadType, 52);
 87        assert_size!(Parameter, 24);
 88    }
 89
 90    #[cfg(target_pointer_width = "64")]
 91    #[test]
 92    fn test_size() {
 93        assert_size!(Description, 72);
 94        assert_size!(Channels, 1);
 95        assert_size!(PayloadType, 80);
 96        assert_size!(Parameter, 48);
 97    }
 98
 99    #[test]
100    fn test_simple() {
101        let elem: Element = "
102<description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio'>
103    <payload-type xmlns='urn:xmpp:jingle:apps:rtp:1' channels='2' clockrate='48000' id='96' name='OPUS'/>
104    <payload-type xmlns='urn:xmpp:jingle:apps:rtp:1' channels='1' clockrate='32000' id='105' name='SPEEX'/>
105    <payload-type xmlns='urn:xmpp:jingle:apps:rtp:1' channels='1' clockrate='8000' id='9' name='G722'/>
106    <payload-type xmlns='urn:xmpp:jingle:apps:rtp:1' channels='1' clockrate='16000' id='106' name='SPEEX'/>
107    <payload-type xmlns='urn:xmpp:jingle:apps:rtp:1' clockrate='8000' id='8' name='PCMA'/>
108    <payload-type xmlns='urn:xmpp:jingle:apps:rtp:1' clockrate='8000' id='0' name='PCMU'/>
109    <payload-type xmlns='urn:xmpp:jingle:apps:rtp:1' channels='1' clockrate='8000' id='107' name='SPEEX'/>
110    <payload-type xmlns='urn:xmpp:jingle:apps:rtp:1' channels='1' clockrate='8000' id='99' name='AMR'>
111        <parameter xmlns='urn:xmpp:jingle:apps:rtp:1' name='octet-align' value='1'/>
112        <parameter xmlns='urn:xmpp:jingle:apps:rtp:1' name='crc' value='0'/>
113        <parameter xmlns='urn:xmpp:jingle:apps:rtp:1' name='robust-sorting' value='0'/>
114        <parameter xmlns='urn:xmpp:jingle:apps:rtp:1' name='interleaving' value='0'/>
115    </payload-type>
116    <payload-type xmlns='urn:xmpp:jingle:apps:rtp:1' clockrate='48000' id='100' name='telephone-event'>
117        <parameter xmlns='urn:xmpp:jingle:apps:rtp:1' name='events' value='0-15'/>
118    </payload-type>
119    <payload-type xmlns='urn:xmpp:jingle:apps:rtp:1' clockrate='16000' id='101' name='telephone-event'>
120        <parameter xmlns='urn:xmpp:jingle:apps:rtp:1' name='events' value='0-15'/>
121    </payload-type>
122    <payload-type xmlns='urn:xmpp:jingle:apps:rtp:1' clockrate='8000' id='102' name='telephone-event'>
123        <parameter xmlns='urn:xmpp:jingle:apps:rtp:1' name='events' value='0-15'/>
124    </payload-type>
125</description>"
126                .parse()
127                .unwrap();
128        let desc = Description::try_from(elem).unwrap();
129        assert_eq!(desc.media, "audio");
130        assert_eq!(desc.ssrc, None);
131    }
132}