diff options
Diffstat (limited to 'Swiften/Parser')
5 files changed, 175 insertions, 1 deletions
diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp index e6f3f60..167f5c1 100644 --- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp +++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp @@ -69,6 +69,7 @@ #include <Swiften/Parser/PayloadParsers/WhiteboardParser.h> #include <Swiften/Parser/PayloadParsers/RTPPayloadTypeParser.h> #include <Swiften/Parser/PayloadParsers/JingleRTPDescriptionParserFactory.h> +#include <Swiften/Parser/PayloadParsers/JingleRawUDPTransportPayloadParser.h> using namespace boost; @@ -132,6 +133,7 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() { factories_.push_back(boost::make_shared<DeliveryReceiptRequestParserFactory>()); factories_.push_back(boost::make_shared<JingleRTPDescriptionParserFactory>(this)); factories_.push_back(boost::make_shared<GenericPayloadParserFactory<RTPPayloadTypeParser> >("payload-type")); + factories_.push_back(boost::make_shared<GenericPayloadParserFactory<JingleRawUDPTransportPayloadParser> >("transport", "urn:xmpp:jingle:transports:raw-udp:1")); foreach(shared_ptr<PayloadParserFactory> factory, factories_) { addFactory(factory.get()); diff --git a/Swiften/Parser/PayloadParsers/JingleRawUDPTransportPayloadParser.cpp b/Swiften/Parser/PayloadParsers/JingleRawUDPTransportPayloadParser.cpp new file mode 100644 index 0000000..aa6aaf7 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleRawUDPTransportPayloadParser.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Parser/PayloadParsers/JingleRawUDPTransportPayloadParser.h> + +#include <boost/lexical_cast.hpp> +#include <boost/optional.hpp> + +namespace Swift { + +JingleRawUDPTransportPayloadParser::JingleRawUDPTransportPayloadParser() : level(0) { + +} + +void JingleRawUDPTransportPayloadParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) { + if (level == 1 && element == "candidate") { + JingleRawUDPTransportPayload::Candidate candidate; + + // component + try { + candidate.component = boost::numeric_cast<boost::uint8_t>(boost::lexical_cast<int>(attributes.getAttributeValue("component").get_value_or("0"))); + } catch(boost::bad_lexical_cast &) { } + // generation + try { + candidate.generation = boost::numeric_cast<boost::uint8_t>(boost::lexical_cast<int>(attributes.getAttributeValue("generation").get_value_or("0"))); + } catch(boost::bad_lexical_cast &) { } + // id + candidate.cid = attributes.getAttributeValue("id").get_value_or(""); + // ip/port + int port = -1; + try { + port = boost::lexical_cast<int>(attributes.getAttributeValue("port").get_value_or("0")); + } catch(boost::bad_lexical_cast &) { } + candidate.hostAddressPort = HostAddressPort(HostAddress(attributes.getAttributeValue("ip").get_value_or("")), port); + // type + candidate.type = stringToType(attributes.getAttributeValue("type").get_value_or("")); + + getPayloadInternal()->addCandidate(candidate); + } + + ++level; +} + +void JingleRawUDPTransportPayloadParser::handleEndElement(const std::string&, const std::string&) { + --level; +} + +void JingleRawUDPTransportPayloadParser::handleCharacterData(const std::string&) { + +} + +JingleRawUDPTransportPayload::Candidate::Type JingleRawUDPTransportPayloadParser::stringToType(const std::string &str) const { + if (str == "host") { + return JingleRawUDPTransportPayload::Candidate::Host; + } else if (str == "prflx") { + return JingleRawUDPTransportPayload::Candidate::PeerReflected; + } else if (str == "relay") { + return JingleRawUDPTransportPayload::Candidate::Relayed; + } else if (str == "srflx") { + return JingleRawUDPTransportPayload::Candidate::ServerReflected; + } else { + return JingleRawUDPTransportPayload::Candidate::Unknown; + } +} + +} diff --git a/Swiften/Parser/PayloadParsers/JingleRawUDPTransportPayloadParser.h b/Swiften/Parser/PayloadParsers/JingleRawUDPTransportPayloadParser.h new file mode 100644 index 0000000..859fe88 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/JingleRawUDPTransportPayloadParser.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 Yoann Blein + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Elements/JingleRawUDPTransportPayload.h> +#include <Swiften/Parser/GenericPayloadParser.h> + +namespace Swift { + +class JingleRawUDPTransportPayloadParser : public GenericPayloadParser<JingleRawUDPTransportPayload> { + public: + JingleRawUDPTransportPayloadParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + + private: + JingleRawUDPTransportPayload::Candidate::Type stringToType(const std::string &str) const; + + private: + int level; +}; + +} diff --git a/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp index 18f38b2..2dd301f 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/JingleParserTest.cpp @@ -15,8 +15,8 @@ #include <Swiften/Elements/StreamInitiationFileInfo.h> #include <Swiften/Elements/JingleFileTransferReceived.h> #include <Swiften/Elements/JingleFileTransferHash.h> -//#include <Swiften/Elements/RTPPayloadType.h> #include <Swiften/Elements/JingleRTPDescription.h> +#include <Swiften/Elements/JingleRawUDPTransportPayload.h> #include <Swiften/Base/DateTime.h> #include <Swiften/Base/Log.h> @@ -47,6 +47,8 @@ class JingleParserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testParse_Xep0167_Example1); CPPUNIT_TEST(testParse_Xep0167_Example48); + CPPUNIT_TEST(testParse_Xep0177_Example3); + CPPUNIT_TEST_SUITE_END(); public: @@ -819,6 +821,77 @@ class JingleParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(std::string("AS"), type); CPPUNIT_ASSERT_EQUAL(std::string("128"), value); } + + // http://xmpp.org/extensions/xep-0177.html#example-3 + void testParse_Xep0177_Example3() { + PayloadsParserTester parser; + CPPUNIT_ASSERT(parser.parse( + "<jingle action=\"session-accept\"" + " initiator=\"romeo@montague.lit/orchard\"" + " responder=\"juliet@capulet.lit/balcony\"" + " sid=\"a73sjjvkla37jfea\"" + " xmlns=\"urn:xmpp:jingle:1\">" + "<content creator=\"initiator\" name=\"voice\">" + "<description media=\"audio\" xmlns=\"urn:xmpp:jingle:apps:rtp:1\">" + "<payload-type id=\"18\" name=\"G729\"/>" + "</description>" + "<transport xmlns=\"urn:xmpp:jingle:transports:raw-udp:1\">" + "<candidate component=\"1\"" + " generation=\"0\"" + " id=\"z7sdjb01hf\"" + " ip=\"208.68.163.214\"" + " port=\"9876\"/>" + "<candidate component=\"2\"" + " generation=\"0\"" + " id=\"hg92lsn10b\"" + " ip=\"208.68.163.214\"" + " port=\"9877\"/>" + "</transport>" + "</content>" + "</jingle>" + )); + + JinglePayload::ref jingle = parser.getPayload<JinglePayload>(); + CPPUNIT_ASSERT(jingle); + CPPUNIT_ASSERT_EQUAL(JinglePayload::SessionAccept, jingle->getAction()); + CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.lit/orchard"), jingle->getInitiator()); + CPPUNIT_ASSERT_EQUAL(JID("juliet@capulet.lit/balcony"), jingle->getResponder()); + CPPUNIT_ASSERT_EQUAL(std::string("a73sjjvkla37jfea"), jingle->getSessionID()); + + JingleContentPayload::ref content = jingle->getPayload<JingleContentPayload>(); + CPPUNIT_ASSERT(content); + CPPUNIT_ASSERT_EQUAL(std::string("voice"), content->getName()); + + JingleRTPDescription::ref desc = content->getDescription<JingleRTPDescription>(); + CPPUNIT_ASSERT(desc); + CPPUNIT_ASSERT_EQUAL(JingleRTPDescription::Audio, desc->getMedia()); + + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), desc->getPayloadTypes().size()); + + const RTPPayloadType& payloadType = desc->getPayloadTypes()[0]; + CPPUNIT_ASSERT_EQUAL(static_cast<boost::uint8_t>(18), payloadType.getID()); + CPPUNIT_ASSERT_EQUAL(std::string("G729"), payloadType.getName()); + + JingleRawUDPTransportPayload::ref transport = content->getTransport<JingleRawUDPTransportPayload>(); + CPPUNIT_ASSERT(transport); + + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), transport->getCandidates().size()); + + const JingleRawUDPTransportPayload::Candidate& candidate1 = transport->getCandidates()[0]; + boost::uint8_t expected = 1; + boost::uint8_t actual = candidate1.component; + + CPPUNIT_ASSERT_EQUAL(expected, actual); + CPPUNIT_ASSERT_EQUAL(static_cast<boost::uint8_t>(0), candidate1.generation); + CPPUNIT_ASSERT_EQUAL(std::string("z7sdjb01hf"), candidate1.cid); + CPPUNIT_ASSERT(HostAddressPort(HostAddress("208.68.163.214"), 9876) == candidate1.hostAddressPort); + + const JingleRawUDPTransportPayload::Candidate& candidate2 = transport->getCandidates()[1]; + CPPUNIT_ASSERT_EQUAL(static_cast<boost::uint8_t>(2), candidate2.component); + CPPUNIT_ASSERT_EQUAL(static_cast<boost::uint8_t>(0), candidate2.generation); + CPPUNIT_ASSERT_EQUAL(std::string("hg92lsn10b"), candidate2.cid); + CPPUNIT_ASSERT(HostAddressPort(HostAddress("208.68.163.214"), 9877) == candidate2.hostAddressPort); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(JingleParserTest); diff --git a/Swiften/Parser/SConscript b/Swiften/Parser/SConscript index 1ce84b9..43d50f0 100644 --- a/Swiften/Parser/SConscript +++ b/Swiften/Parser/SConscript @@ -75,6 +75,7 @@ sources = [ "PayloadParsers/WhiteboardParser.cpp", "PayloadParsers/RTPPayloadTypeParser.cpp", "PayloadParsers/JingleRTPDescriptionParser.cpp", + "PayloadParsers/JingleRawUDPTransportPayloadParser.cpp", "PlatformXMLParserFactory.cpp", "PresenceParser.cpp", "SerializingParser.cpp", |