diff --git a/xmpp-parsers/doap.xml b/xmpp-parsers/doap.xml
index 72252f03..ac382652 100644
--- a/xmpp-parsers/doap.xml
+++ b/xmpp-parsers/doap.xml
@@ -240,6 +240,14 @@
0.13.0
+
+
+
+ complete
+ 1.1
+ NEXT
+
+
diff --git a/xmpp-parsers/src/jingle_raw_udp.rs b/xmpp-parsers/src/jingle_raw_udp.rs
new file mode 100644
index 00000000..9197980c
--- /dev/null
+++ b/xmpp-parsers/src/jingle_raw_udp.rs
@@ -0,0 +1,102 @@
+// Copyright (c) 2020 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_ice_udp::Type;
+use std::net::IpAddr;
+
+generate_element!(
+ /// Wrapper element for an raw UDP transport.
+ Transport, "transport", JINGLE_RAW_UDP,
+ children: [
+ /// List of candidates for this raw UDP session.
+ candidates: Vec = ("candidate", JINGLE_RAW_UDP) => Candidate
+ ]
+);
+
+impl Transport {
+ /// Create a new ICE-UDP transport.
+ pub fn new() -> Transport {
+ Transport {
+ candidates: Vec::new(),
+ }
+ }
+
+ /// Add a candidate to this transport.
+ pub fn add_candidate(mut self, candidate: Candidate) -> Self {
+ self.candidates.push(candidate);
+ self
+ }
+}
+
+generate_element!(
+ /// A candidate for an ICE-UDP session.
+ Candidate, "candidate", JINGLE_RAW_UDP,
+ attributes: [
+ /// A Component ID as defined in ICE-CORE.
+ component: Required = "component",
+
+ /// An index, starting at 0, that enables the parties to keep track of updates to the
+ /// candidate throughout the life of the session.
+ generation: Required = "generation",
+
+ /// A unique identifier for the candidate.
+ id: Required = "id",
+
+ /// The Internet Protocol (IP) address for the candidate transport mechanism; this can be
+ /// either an IPv4 address or an IPv6 address.
+ ip: Required = "ip",
+
+ /// The port at the candidate IP address.
+ port: Required = "port",
+
+ /// A Candidate Type as defined in ICE-CORE.
+ type_: Option = "type",
+ ]
+);
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::Element;
+ use std::convert::TryFrom;
+
+ #[cfg(target_pointer_width = "32")]
+ #[test]
+ fn test_size() {
+ assert_size!(Transport, 12);
+ assert_size!(Candidate, 40);
+ }
+
+ #[cfg(target_pointer_width = "64")]
+ #[test]
+ fn test_size() {
+ assert_size!(Transport, 24);
+ assert_size!(Candidate, 56);
+ }
+
+ #[test]
+ fn example_1() {
+ let elem: Element = "
+
+
+"
+ .parse()
+ .unwrap();
+ let mut transport = Transport::try_from(elem).unwrap();
+ assert_eq!(transport.candidates.len(), 1);
+ let candidate = transport.candidates.pop().unwrap();
+ assert_eq!(candidate.component, 1);
+ assert_eq!(candidate.generation, 0);
+ assert_eq!(candidate.id, "a9j3mnbtu1");
+ assert_eq!(candidate.ip, "10.1.1.104".parse::().unwrap());
+ assert_eq!(candidate.port, 13540u16);
+ assert!(candidate.type_.is_none());
+ }
+}
diff --git a/xmpp-parsers/src/lib.rs b/xmpp-parsers/src/lib.rs
index 4ffee2bb..673e7e49 100644
--- a/xmpp-parsers/src/lib.rs
+++ b/xmpp-parsers/src/lib.rs
@@ -120,6 +120,9 @@ pub mod nick;
/// XEP-0176: Jingle ICE-UDP Transport Method
pub mod jingle_ice_udp;
+/// XEP-0177: Jingle Raw UDP Transport Method
+pub mod jingle_raw_udp;
+
/// XEP-0184: Message Delivery Receipts
pub mod receipts;
diff --git a/xmpp-parsers/src/ns.rs b/xmpp-parsers/src/ns.rs
index 345cc4dd..9acb7fbf 100644
--- a/xmpp-parsers/src/ns.rs
+++ b/xmpp-parsers/src/ns.rs
@@ -110,6 +110,9 @@ pub const NICK: &str = "http://jabber.org/protocol/nick";
/// XEP-0176: Jingle ICE-UDP Transport Method
pub const JINGLE_ICE_UDP: &str = "urn:xmpp:jingle:transports:ice-udp:1";
+/// XEP-0177: Jingle Raw UDP Transport Method
+pub const JINGLE_RAW_UDP: &str = "urn:xmpp:jingle:transports:raw-udp:1";
+
/// XEP-0184: Message Delivery Receipts
pub const RECEIPTS: &str = "urn:xmpp:receipts";