// 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 crate::jingle_ssma::{Source, Group}; use crate::jingle_rtcp_fb::RtcpFb; generate_element!( /// Wrapper element describing an RTP session. Description, "description", JINGLE_RTP, attributes: [ /// Namespace of the encryption scheme used. media: Required = "media", /// User-friendly name for the encryption scheme, should be `None` for OTR, /// legacy OpenPGP and OX. // XXX: is this a String or an u32?! Refer to RFC 3550. ssrc: Option = "ssrc", ], children: [ /// List of encodings that can be used for this RTP stream. payload_types: Vec = ("payload-type", JINGLE_RTP) => PayloadType, /// List of ssrc-group. ssrc_groups: Vec = ("ssrc-group", JINGLE_SSMA) => Group, /// List of ssrc. ssrcs: Vec = ("source", JINGLE_SSMA) => Source // TODO: Add support for and . ] ); impl Description { /// Create a new RTP description. pub fn new(media: String) -> Description { Description { media, ssrc: None, payload_types: Vec::new(), ssrc_groups: Vec::new(), ssrcs: Vec::new(), } } } generate_attribute!( /// The number of channels. Channels, "channels", u8, Default = 1 ); generate_element!( /// An encoding that can be used for an RTP stream. PayloadType, "payload-type", JINGLE_RTP, attributes: [ /// The number of channels. channels: Default = "channels", /// The sampling frequency in Hertz. clockrate: Option = "clockrate", /// The payload identifier. id: Required = "id", /// Maximum packet time as specified in RFC 4566. maxptime: Option = "maxptime", /// The appropriate subtype of the MIME type. name: Option = "name", /// Packet time as specified in RFC 4566. ptime: Option = "ptime", ], children: [ /// List of parameters specifying this payload-type. /// /// Their order MUST be ignored. parameters: Vec = ("parameter", JINGLE_RTP) => Parameter, /// List of rtcp-fb parameters from XEP-0293. rtcp_fbs: Vec = ("rtcp-fb", JINGLE_RTCP_FB) => RtcpFb ] ); impl PayloadType { /// Create a new RTP payload-type. pub fn new(id: u8, name: String) -> PayloadType { PayloadType { channels: Default::default(), clockrate: None, id, maxptime: None, name: Some(name), ptime: None, parameters: Vec::new(), rtcp_fbs: Vec::new(), } } } generate_element!( /// Parameter related to a payload. Parameter, "parameter", JINGLE_RTP, attributes: [ /// The name of the parameter, from the list at /// https://www.iana.org/assignments/sdp-parameters/sdp-parameters.xhtml name: Required = "name", /// The value of this parameter. value: Required = "value", ] ); #[cfg(test)] mod tests { use super::*; use crate::Element; use std::convert::TryFrom; #[cfg(target_pointer_width = "32")] #[test] fn test_size() { assert_size!(Description, 36); assert_size!(Channels, 1); assert_size!(PayloadType, 52); assert_size!(Parameter, 24); } #[cfg(target_pointer_width = "64")] #[test] fn test_size() { assert_size!(Description, 120); assert_size!(Channels, 1); assert_size!(PayloadType, 104); assert_size!(Parameter, 48); } #[test] fn test_simple() { let elem: Element = " " .parse() .unwrap(); let desc = Description::try_from(elem).unwrap(); assert_eq!(desc.media, "audio"); assert_eq!(desc.ssrc, None); } }