diff options
Diffstat (limited to 'Swiften/Jingle')
-rw-r--r-- | Swiften/Jingle/FakeJingleSession.cpp | 52 | ||||
-rw-r--r-- | Swiften/Jingle/FakeJingleSession.h | 93 | ||||
-rw-r--r-- | Swiften/Jingle/IncomingJingleSession.cpp | 15 | ||||
-rw-r--r-- | Swiften/Jingle/IncomingJingleSession.h | 20 | ||||
-rw-r--r-- | Swiften/Jingle/IncomingJingleSessionHandler.h | 4 | ||||
-rw-r--r-- | Swiften/Jingle/Jingle.h | 25 | ||||
-rw-r--r-- | Swiften/Jingle/JingleContentID.h | 31 | ||||
-rw-r--r-- | Swiften/Jingle/JingleResponder.cpp | 29 | ||||
-rw-r--r-- | Swiften/Jingle/JingleResponder.h | 3 | ||||
-rw-r--r-- | Swiften/Jingle/JingleSession.cpp | 16 | ||||
-rw-r--r-- | Swiften/Jingle/JingleSession.h | 52 | ||||
-rw-r--r-- | Swiften/Jingle/JingleSessionImpl.cpp | 185 | ||||
-rw-r--r-- | Swiften/Jingle/JingleSessionImpl.h | 42 | ||||
-rw-r--r-- | Swiften/Jingle/JingleSessionManager.cpp | 23 | ||||
-rw-r--r-- | Swiften/Jingle/JingleSessionManager.h | 17 | ||||
-rw-r--r-- | Swiften/Jingle/SConscript | 5 |
16 files changed, 515 insertions, 97 deletions
diff --git a/Swiften/Jingle/FakeJingleSession.cpp b/Swiften/Jingle/FakeJingleSession.cpp new file mode 100644 index 0000000..82ec631 --- /dev/null +++ b/Swiften/Jingle/FakeJingleSession.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Jingle/FakeJingleSession.h> + +#include <boost/smart_ptr/make_shared.hpp> + +namespace Swift { + +FakeJingleSession::FakeJingleSession(const JID& initiator, const std::string& id) : JingleSession(initiator, id) { + +} + +FakeJingleSession::~FakeJingleSession() { +} + +void FakeJingleSession::sendInitiate(const JingleContentID& id, JingleDescription::ref desc, JingleTransportPayload::ref payload) { + calledCommands.push_back(InitiateCall(id, desc, payload)); +} + +void FakeJingleSession::sendTerminate(JinglePayload::Reason::Type reason) { + calledCommands.push_back(TerminateCall(reason)); +} + +void FakeJingleSession::sendInfo(boost::shared_ptr<Payload> payload) { + calledCommands.push_back(InfoCall(payload)); +} + +void FakeJingleSession::sendAccept(const JingleContentID& id, JingleDescription::ref desc, JingleTransportPayload::ref payload) { + calledCommands.push_back(AcceptCall(id, desc, payload)); +} + +void FakeJingleSession::sendTransportInfo(const JingleContentID& id, JingleTransportPayload::ref payload) { + calledCommands.push_back(InfoTransportCall(id, payload)); +} + +void FakeJingleSession::sendTransportAccept(const JingleContentID& id, JingleTransportPayload::ref payload) { + calledCommands.push_back(AcceptTransportCall(id, payload)); +} + +void FakeJingleSession::sendTransportReject(const JingleContentID& id, JingleTransportPayload::ref payload) { + calledCommands.push_back(RejectTransportCall(id, payload)); +} + +void FakeJingleSession::sendTransportReplace(const JingleContentID& id, JingleTransportPayload::ref payload) { + calledCommands.push_back(ReplaceTransportCall(id, payload)); +} + +} diff --git a/Swiften/Jingle/FakeJingleSession.h b/Swiften/Jingle/FakeJingleSession.h new file mode 100644 index 0000000..fd3d7b7 --- /dev/null +++ b/Swiften/Jingle/FakeJingleSession.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> +#include <string> +#include <vector> +#include <boost/variant.hpp> + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/JinglePayload.h> +#include <Swiften/Jingle/JingleSession.h> +#include <Swiften/Jingle/JingleContentID.h> + +namespace Swift { + class JingleContentID; + + class FakeJingleSession : public JingleSession { + public: + struct InitiateCall { + InitiateCall(JingleContentID contentId, JingleDescription::ref desc, JingleTransportPayload::ref payL) : id(contentId), description(desc), payload(payL) {} + JingleContentID id; + JingleDescription::ref description; + JingleTransportPayload::ref payload; + }; + + struct TerminateCall { + TerminateCall(JinglePayload::Reason::Type r) : reason(r) {} + JinglePayload::Reason::Type reason; + }; + + struct InfoCall { + InfoCall(boost::shared_ptr<Payload> info) : payload(info) {} + boost::shared_ptr<Payload> payload; + }; + + struct AcceptCall { + AcceptCall(JingleContentID contentId, JingleDescription::ref desc, JingleTransportPayload::ref payL) : id(contentId), description(desc), payload(payL) {} + JingleContentID id; + JingleDescription::ref description; + JingleTransportPayload::ref payload; + }; + + struct InfoTransportCall { + InfoTransportCall(JingleContentID contentId, JingleTransportPayload::ref payL) : id(contentId), payload(payL) {} + JingleContentID id; + JingleTransportPayload::ref payload; + }; + + struct AcceptTransportCall { + AcceptTransportCall(JingleContentID contentId, JingleTransportPayload::ref payL) : id(contentId), payload(payL) {} + JingleContentID id; + JingleTransportPayload::ref payload; + }; + + struct RejectTransportCall { + RejectTransportCall(JingleContentID contentId, JingleTransportPayload::ref payL) : id(contentId), payload(payL) {} + JingleContentID id; + JingleTransportPayload::ref payload; + }; + + struct ReplaceTransportCall { + ReplaceTransportCall(JingleContentID contentId, JingleTransportPayload::ref payL) : id(contentId), payload(payL) {} + JingleContentID id; + JingleTransportPayload::ref payload; + }; + + typedef boost::variant<InitiateCall, TerminateCall, AcceptCall, InfoCall, InfoTransportCall, AcceptTransportCall, RejectTransportCall, ReplaceTransportCall> Command; + + public: + typedef boost::shared_ptr<FakeJingleSession> ref; + + FakeJingleSession(const JID& initiator, const std::string& id); + virtual ~FakeJingleSession(); + + virtual void sendInitiate(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref); + virtual void sendTerminate(JinglePayload::Reason::Type reason); + virtual void sendInfo(boost::shared_ptr<Payload>); + virtual void sendAccept(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref = JingleTransportPayload::ref()); + virtual void sendTransportInfo(const JingleContentID&, JingleTransportPayload::ref); + virtual void sendTransportAccept(const JingleContentID&, JingleTransportPayload::ref); + virtual void sendTransportReject(const JingleContentID&, JingleTransportPayload::ref); + virtual void sendTransportReplace(const JingleContentID&, JingleTransportPayload::ref); + + public: + std::vector<Command> calledCommands; + }; +} diff --git a/Swiften/Jingle/IncomingJingleSession.cpp b/Swiften/Jingle/IncomingJingleSession.cpp deleted file mode 100644 index b18d9d3..0000000 --- a/Swiften/Jingle/IncomingJingleSession.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include <Swiften/Jingle/IncomingJingleSession.h> - -namespace Swift { - -IncomingJingleSession::IncomingJingleSession(const std::string& id, const std::vector<JingleContent::ref>& contents) : JingleSession(id, contents) { - -} - -} diff --git a/Swiften/Jingle/IncomingJingleSession.h b/Swiften/Jingle/IncomingJingleSession.h deleted file mode 100644 index 64816f6..0000000 --- a/Swiften/Jingle/IncomingJingleSession.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2011 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#pragma once - -#include <boost/shared_ptr.hpp> - -#include <Swiften/Jingle/JingleSession.h> - -namespace Swift { - class IncomingJingleSession : public JingleSession { - public: - IncomingJingleSession(const std::string& id, const std::vector<JingleContent::ref>& contents); - - typedef boost::shared_ptr<IncomingJingleSession> ref; - }; -} diff --git a/Swiften/Jingle/IncomingJingleSessionHandler.h b/Swiften/Jingle/IncomingJingleSessionHandler.h index 5bf9237..d23570d 100644 --- a/Swiften/Jingle/IncomingJingleSessionHandler.h +++ b/Swiften/Jingle/IncomingJingleSessionHandler.h @@ -6,13 +6,13 @@ #pragma once -#include <Swiften/Jingle/IncomingJingleSession.h> +#include <Swiften/Jingle/JingleSession.h> namespace Swift { class IncomingJingleSessionHandler { public: virtual ~IncomingJingleSessionHandler(); - virtual bool handleIncomingJingleSession(IncomingJingleSession::ref) = 0; + virtual bool handleIncomingJingleSession(JingleSession::ref, const std::vector<JingleContentPayload::ref>& contents, const JID& recipient) = 0; }; } diff --git a/Swiften/Jingle/Jingle.h b/Swiften/Jingle/Jingle.h new file mode 100644 index 0000000..ba4dfe3 --- /dev/null +++ b/Swiften/Jingle/Jingle.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> + +#include <Swiften/Elements/JingleContentPayload.h> + +namespace Swift { + namespace Jingle { + template<typename T> + JingleContentPayload::ref getContentWithDescription(const std::vector<JingleContentPayload::ref>& contents) { + for (size_t i = 0; i < contents.size(); ++i) { + if (contents[i]->getDescription<T>()) { + return contents[i]; + } + } + return JingleContentPayload::ref(); + } + } +} diff --git a/Swiften/Jingle/JingleContentID.h b/Swiften/Jingle/JingleContentID.h new file mode 100644 index 0000000..fc0cc8f --- /dev/null +++ b/Swiften/Jingle/JingleContentID.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <string> + +#include <Swiften/Elements/JingleContentPayload.h> + +namespace Swift { + class JingleContentID { + public: + JingleContentID(const std::string& name, JingleContentPayload::Creator creator) : name(name), creator(creator) { + } + + const std::string getName() const { + return this->name; + } + + JingleContentPayload::Creator getCreator() const { + return this->creator; + } + + private: + std::string name; + JingleContentPayload::Creator creator; + }; +} diff --git a/Swiften/Jingle/JingleResponder.cpp b/Swiften/Jingle/JingleResponder.cpp index 2397e63..4c82f51 100644 --- a/Swiften/Jingle/JingleResponder.cpp +++ b/Swiften/Jingle/JingleResponder.cpp @@ -9,14 +9,19 @@ #include <boost/smart_ptr/make_shared.hpp> #include <Swiften/Jingle/JingleSessionManager.h> -#include <Swiften/Jingle/IncomingJingleSession.h> +#include <Swiften/Jingle/JingleSessionImpl.h> + +#include <Swiften/Base/Log.h> namespace Swift { -JingleResponder::JingleResponder(JingleSessionManager* sessionManager, IQRouter* router) : SetResponder<JinglePayload>(router), sessionManager(sessionManager) { +JingleResponder::JingleResponder(JingleSessionManager* sessionManager, IQRouter* router) : SetResponder<JinglePayload>(router), sessionManager(sessionManager), router(router) { +} + +JingleResponder::~JingleResponder() { } -bool JingleResponder::handleSetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<JinglePayload> payload) { +bool JingleResponder::handleSetRequest(const JID& from, const JID& to, const std::string& id, boost::shared_ptr<JinglePayload> payload) { if (payload->getAction() == JinglePayload::SessionInitiate) { if (sessionManager->getSession(from, payload->getSessionID())) { // TODO: Add tie-break error @@ -24,17 +29,29 @@ bool JingleResponder::handleSetRequest(const JID& from, const JID&, const std::s } else { sendResponse(from, id, boost::shared_ptr<JinglePayload>()); - IncomingJingleSession::ref session = boost::make_shared<IncomingJingleSession>(id, payload->getContents()); - sessionManager->handleIncomingSession(from, session); + if (!payload->getInitiator().isBare()) { + JingleSessionImpl::ref session = boost::make_shared<JingleSessionImpl>(payload->getInitiator(), from, payload->getSessionID(), router); + sessionManager->handleIncomingSession(from, to, session, payload->getContents()); + } else { + SWIFT_LOG(debug) << "Unable to create Jingle session due to initiator not being a full JID." << std::endl; + } } } else { - JingleSession::ref session = sessionManager->getSession(from, payload->getSessionID()); + JingleSessionImpl::ref session; + if (payload->getInitiator().isValid()) { + SWIFT_LOG(debug) << "Lookup session by initiator." << std::endl; + session = sessionManager->getSession(payload->getInitiator(), payload->getSessionID()); + } else { + SWIFT_LOG(debug) << "Lookup session by from attribute." << std::endl; + session = sessionManager->getSession(from, payload->getSessionID()); + } if (session) { session->handleIncomingAction(payload); sendResponse(from, id, boost::shared_ptr<JinglePayload>()); } else { + std::cerr << "WARN: Didn't find jingle session!" << std::endl; // TODO: Add jingle-specific error sendError(from, id, ErrorPayload::ItemNotFound, ErrorPayload::Cancel); } diff --git a/Swiften/Jingle/JingleResponder.h b/Swiften/Jingle/JingleResponder.h index 6e1965c..6f4d688 100644 --- a/Swiften/Jingle/JingleResponder.h +++ b/Swiften/Jingle/JingleResponder.h @@ -16,11 +16,12 @@ namespace Swift { class JingleResponder : public SetResponder<JinglePayload> { public: JingleResponder(JingleSessionManager* sessionManager, IQRouter* router); - + virtual ~JingleResponder(); private: virtual bool handleSetRequest(const JID& from, const JID& to, const std::string& id, boost::shared_ptr<JinglePayload> payload); private: JingleSessionManager* sessionManager; + IQRouter* router; }; } diff --git a/Swiften/Jingle/JingleSession.cpp b/Swiften/Jingle/JingleSession.cpp index d255abd..eb649f3 100644 --- a/Swiften/Jingle/JingleSession.cpp +++ b/Swiften/Jingle/JingleSession.cpp @@ -10,21 +10,13 @@ namespace Swift { -JingleSession::JingleSession(const std::string& id, const std::vector<JingleContent::ref>& contents) : id(id), contents(contents) { - +JingleSession::JingleSession(const JID& initiator, const std::string& id) : initiator(initiator), id(id) { + // initiator must always be a full JID; session lookup based on it wouldn't work otherwise + // this is checked on an upper level so that the assert never fails + assert(!initiator.isBare()); } JingleSession::~JingleSession() { } -void JingleSession::handleIncomingAction(JinglePayload::ref) { -} - -void JingleSession::terminate(JinglePayload::Reason::Type reason) { - JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionTerminate, id); - payload->setReason(JinglePayload::Reason(reason)); - //onAction(payload) -} - - } diff --git a/Swiften/Jingle/JingleSession.h b/Swiften/Jingle/JingleSession.h index fe8aa01..150ad79 100644 --- a/Swiften/Jingle/JingleSession.h +++ b/Swiften/Jingle/JingleSession.h @@ -7,47 +7,51 @@ #pragma once #include <boost/shared_ptr.hpp> +#include <boost/optional.hpp> -#include <Swiften/Base/boost_bsignals.h> #include <string> + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/JID/JID.h> #include <Swiften/Elements/JinglePayload.h> -#include <Swiften/Elements/JingleContent.h> -#include <Swiften/Base/foreach.h> namespace Swift { + class JingleContentID; + class JingleSession { - friend class JingleResponder; public: typedef boost::shared_ptr<JingleSession> ref; - JingleSession(const std::string& id, const std::vector<JingleContent::ref>& contents); + JingleSession(const JID& initiator, const std::string& id); virtual ~JingleSession(); - std::string getID() const { - return id; + const JID& getInitiator() const { + return initiator; } - template<typename T> - JingleContent::ref getContentWithDescription() const { - foreach (JingleContent::ref content, contents) { - if (content->getDescription<T>()) { - return content; - } - } - return JingleContent::ref(); - } - - const std::vector<JingleContent::ref>& getContents() const { - return contents; + const std::string& getID() const { + return id; } + virtual void sendInitiate(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref) = 0; + virtual void sendTerminate(JinglePayload::Reason::Type reason) = 0; + virtual void sendInfo(boost::shared_ptr<Payload>) = 0; + virtual void sendAccept(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref = JingleTransportPayload::ref()) = 0; + virtual void sendTransportInfo(const JingleContentID&, JingleTransportPayload::ref) = 0; + virtual void sendTransportAccept(const JingleContentID&, JingleTransportPayload::ref) = 0; + virtual void sendTransportReject(const JingleContentID&, JingleTransportPayload::ref) = 0; + virtual void sendTransportReplace(const JingleContentID&, JingleTransportPayload::ref) = 0; - void terminate(JinglePayload::Reason::Type reason); - - private: - void handleIncomingAction(JinglePayload::ref); + public: + boost::signal<void (const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref)> onSessionAcceptReceived; + boost::signal<void (JinglePayload::ref)> onSessionInfoReceived; + boost::signal<void (boost::optional<JinglePayload::Reason>)> onSessionTerminateReceived; + boost::signal<void (const JingleContentID&, JingleTransportPayload::ref)> onTransportAcceptReceived; + boost::signal<void (const JingleContentID&, JingleTransportPayload::ref)> onTransportInfoReceived; + boost::signal<void (const JingleContentID&, JingleTransportPayload::ref)> onTransportRejectReceived; + boost::signal<void (const JingleContentID&, JingleTransportPayload::ref)> onTransportReplaceReceived; private: + JID initiator; std::string id; - std::vector<JingleContent::ref> contents; }; } diff --git a/Swiften/Jingle/JingleSessionImpl.cpp b/Swiften/Jingle/JingleSessionImpl.cpp new file mode 100644 index 0000000..98c5196 --- /dev/null +++ b/Swiften/Jingle/JingleSessionImpl.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Jingle/JingleSessionImpl.h> + +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Parser/PayloadParsers/JingleParser.h> +#include <Swiften/Jingle/JingleContentID.h> +#include <Swiften/Elements/JingleContentPayload.h> +#include <Swiften/Queries/Request.h> +#include <Swiften/Queries/GenericRequest.h> + +#include <Swiften/Base/Log.h> + +#include "Swiften/Serializer/PayloadSerializers/JinglePayloadSerializer.h" +#include "Swiften/FileTransfer/JingleTransport.h" + +namespace Swift { + +JingleSessionImpl::JingleSessionImpl(const JID& initiator, const JID& peerJID, const std::string& id, IQRouter* router) : JingleSession(initiator, id), iqRouter(router), peerJID(peerJID) { + SWIFT_LOG(debug) << "initiator: " << initiator << ", peerJID: " << peerJID << std::endl; +} + +void JingleSessionImpl::handleIncomingAction(JinglePayload::ref action) { + if (action->getAction() == JinglePayload::SessionTerminate) { + onSessionTerminateReceived(action->getReason()); + return; + } + if (action->getAction() == JinglePayload::SessionInfo) { + onSessionInfoReceived(action); + return; + } + + JingleContentPayload::ref content = action->getPayload<JingleContentPayload>(); + if (!content) { + SWIFT_LOG(debug) << "no content payload!" << std::endl; + return; + } + JingleContentID contentID(content->getName(), content->getCreator()); + JingleDescription::ref description = content->getDescriptions().empty() ? JingleDescription::ref() : content->getDescriptions()[0]; + JingleTransportPayload::ref transport = content->getTransports().empty() ? JingleTransportPayload::ref() : content->getTransports()[0]; + switch(action->getAction()) { + case JinglePayload::SessionAccept: + onSessionAcceptReceived(contentID, description, transport); + return; + case JinglePayload::TransportAccept: + onTransportAcceptReceived(contentID, transport); + return; + case JinglePayload::TransportInfo: + onTransportInfoReceived(contentID, transport); + return; + case JinglePayload::TransportReject: + onTransportRejectReceived(contentID, transport); + return; + case JinglePayload::TransportReplace: + onTransportReplaceReceived(contentID, transport); + return; + // following unused Jingle actions + case JinglePayload::ContentAccept: + case JinglePayload::ContentAdd: + case JinglePayload::ContentModify: + case JinglePayload::ContentReject: + case JinglePayload::ContentRemove: + case JinglePayload::DescriptionInfo: + case JinglePayload::SecurityInfo: + + // handled elsewhere + case JinglePayload::SessionInitiate: + case JinglePayload::SessionInfo: + case JinglePayload::SessionTerminate: + + case JinglePayload::UnknownAction: + return; + } + std::cerr << "Unhandled Jingle action!!! ACTION: " << action->getAction() << std::endl; +} + +void JingleSessionImpl::sendInitiate(const JingleContentID& id, JingleDescription::ref description, JingleTransportPayload::ref transport) { + JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionInitiate, getID()); + payload->setInitiator(getInitiator()); + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(id.getCreator()); + content->setName(id.getName()); + content->addDescription(description); + content->addTransport(transport); + payload->addPayload(content); + + sendSetRequest(payload); +} + +void JingleSessionImpl::sendTerminate(JinglePayload::Reason::Type reason) { + JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionTerminate, getID()); + payload->setReason(JinglePayload::Reason(reason)); + payload->setInitiator(getInitiator()); + sendSetRequest(payload); +} + +void JingleSessionImpl::sendInfo(boost::shared_ptr<Payload> info) { + JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionInfo, getID()); + payload->addPayload(info); + + sendSetRequest(payload); +} + +void JingleSessionImpl::sendAccept(const JingleContentID& id, JingleDescription::ref description, JingleTransportPayload::ref transPayload) { + JinglePayload::ref payload = createPayload(); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(id.getCreator()); + content->setName(id.getName()); + content->addTransport(transPayload); + content->addDescription(description); + payload->setAction(JinglePayload::SessionAccept); + payload->addPayload(content); + + // put into IQ:set and send it away + sendSetRequest(payload); +} + + +void JingleSessionImpl::sendTransportAccept(const JingleContentID& id, JingleTransportPayload::ref transPayload) { + JinglePayload::ref payload = createPayload(); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(id.getCreator()); + content->setName(id.getName()); + content->addTransport(transPayload); + payload->setAction(JinglePayload::TransportAccept); + payload->addPayload(content); + + // put into IQ:set and send it away + sendSetRequest(payload); +} + +void JingleSessionImpl::sendTransportInfo(const JingleContentID& id, JingleTransportPayload::ref transPayload) { + JinglePayload::ref payload = createPayload(); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(id.getCreator()); + content->setName(id.getName()); + content->addTransport(transPayload); + payload->setAction(JinglePayload::TransportInfo); + payload->addPayload(content); + + sendSetRequest(payload); +} + +void JingleSessionImpl::sendTransportReject(const JingleContentID& /* id */, JingleTransportPayload::ref /* transPayload */) { + SWIFT_LOG(debug) << "NOT IMPLEMENTED YET!!!!" << std::endl; +} + +void JingleSessionImpl::sendTransportReplace(const JingleContentID& id, JingleTransportPayload::ref transPayload) { + JinglePayload::ref payload = createPayload(); + + JingleContentPayload::ref content = boost::make_shared<JingleContentPayload>(); + content->setCreator(id.getCreator()); + content->setName(id.getName()); + content->addTransport(transPayload); + payload->setAction(JinglePayload::TransportReplace); + payload->addContent(content); + + sendSetRequest(payload); +} + + +void JingleSessionImpl::sendSetRequest(JinglePayload::ref payload) { + boost::shared_ptr<GenericRequest<JinglePayload> > request = boost::make_shared<GenericRequest<JinglePayload> >(IQ::Set, peerJID, payload, iqRouter); + request->send(); +} + + +JinglePayload::ref JingleSessionImpl::createPayload() const { + JinglePayload::ref payload = boost::make_shared<JinglePayload>(); + payload->setSessionID(getID()); + payload->setInitiator(getInitiator()); + return payload; +} + + + +} diff --git a/Swiften/Jingle/JingleSessionImpl.h b/Swiften/Jingle/JingleSessionImpl.h new file mode 100644 index 0000000..3c1559a --- /dev/null +++ b/Swiften/Jingle/JingleSessionImpl.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> + +#include <Swiften/Jingle/JingleSession.h> + +namespace Swift { + class IQRouter; + + class JingleSessionImpl : public JingleSession { + friend class JingleResponder; + public: + typedef boost::shared_ptr<JingleSessionImpl> ref; + + JingleSessionImpl(const JID& initiator, const JID&, const std::string& id, IQRouter* router); + + virtual void sendInitiate(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref); + virtual void sendTerminate(JinglePayload::Reason::Type reason); + virtual void sendInfo(boost::shared_ptr<Payload>); + virtual void sendAccept(const JingleContentID&, JingleDescription::ref, JingleTransportPayload::ref); + virtual void sendTransportInfo(const JingleContentID&, JingleTransportPayload::ref); + virtual void sendTransportAccept(const JingleContentID&, JingleTransportPayload::ref); + virtual void sendTransportReject(const JingleContentID&, JingleTransportPayload::ref); + virtual void sendTransportReplace(const JingleContentID&, JingleTransportPayload::ref); + + private: + void handleIncomingAction(JinglePayload::ref); + + void sendSetRequest(JinglePayload::ref payload); + JinglePayload::ref createPayload() const; + + private: + IQRouter *iqRouter; + JID peerJID; + }; +} diff --git a/Swiften/Jingle/JingleSessionManager.cpp b/Swiften/Jingle/JingleSessionManager.cpp index e60449b..2e15fcd 100644 --- a/Swiften/Jingle/JingleSessionManager.cpp +++ b/Swiften/Jingle/JingleSessionManager.cpp @@ -7,20 +7,24 @@ #include <Swiften/Jingle/JingleSessionManager.h> #include <Swiften/Jingle/JingleResponder.h> #include <Swiften/Jingle/IncomingJingleSessionHandler.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Base/Algorithm.h> namespace Swift { JingleSessionManager::JingleSessionManager(IQRouter* router) : router(router) { responder = new JingleResponder(this, router); + responder->start(); } JingleSessionManager::~JingleSessionManager() { + responder->stop(); delete responder; } -JingleSession::ref JingleSessionManager::getSession(const JID& jid, const std::string& id) const { - SessionMap::const_iterator i = incomingSessions.find(JIDSession(jid, id)); - return i != incomingSessions.end() ? i->second : JingleSession::ref(); +JingleSessionImpl::ref JingleSessionManager::getSession(const JID& jid, const std::string& id) const { + SessionMap::const_iterator i = sessions.find(JIDSession(jid, id)); + return i != sessions.end() ? i->second : JingleSessionImpl::ref(); } void JingleSessionManager::addIncomingSessionHandler(IncomingJingleSessionHandler* handler) { @@ -28,13 +32,18 @@ void JingleSessionManager::addIncomingSessionHandler(IncomingJingleSessionHandle } void JingleSessionManager::removeIncomingSessionHandler(IncomingJingleSessionHandler* handler) { - incomingSessionHandlers.erase(std::remove(incomingSessionHandlers.begin(), incomingSessionHandlers.end(), handler), incomingSessionHandlers.end()); + erase(incomingSessionHandlers, handler); } -void JingleSessionManager::handleIncomingSession(const JID& from, IncomingJingleSession::ref session) { - incomingSessions.insert(std::make_pair(JIDSession(from, session->getID()), session)); +void JingleSessionManager::registerOutgoingSession(const JID& initiator, JingleSessionImpl::ref session) { + sessions.insert(std::make_pair(JIDSession(initiator, session->getID()), session)); + SWIFT_LOG(debug) << "Added session " << session->getID() << " for initiator " << initiator.toString() << std::endl; +} + +void JingleSessionManager::handleIncomingSession(const JID& initiator, const JID& recipient, JingleSessionImpl::ref session, const std::vector<JingleContentPayload::ref>& contents) { + sessions.insert(std::make_pair(JIDSession(initiator, session->getID()), session)); foreach (IncomingJingleSessionHandler* handler, incomingSessionHandlers) { - if (handler->handleIncomingJingleSession(session)) { + if (handler->handleIncomingJingleSession(session, contents, recipient)) { return; } } diff --git a/Swiften/Jingle/JingleSessionManager.h b/Swiften/Jingle/JingleSessionManager.h index 3e99656..b4f2846 100644 --- a/Swiften/Jingle/JingleSessionManager.h +++ b/Swiften/Jingle/JingleSessionManager.h @@ -10,7 +10,7 @@ #include <map> #include <Swiften/Base/boost_bsignals.h> -#include <Swiften/Jingle/IncomingJingleSession.h> +#include <Swiften/Jingle/JingleSessionImpl.h> namespace Swift { class IQRouter; @@ -23,27 +23,28 @@ namespace Swift { JingleSessionManager(IQRouter* router); ~JingleSessionManager(); - JingleSession::ref getSession(const JID& jid, const std::string& id) const; + JingleSessionImpl::ref getSession(const JID& jid, const std::string& id) const; void addIncomingSessionHandler(IncomingJingleSessionHandler* handler); void removeIncomingSessionHandler(IncomingJingleSessionHandler* handler); + void registerOutgoingSession(const JID& initiator, JingleSessionImpl::ref); protected: - void handleIncomingSession(const JID& from, IncomingJingleSession::ref); + void handleIncomingSession(const JID& initiator, const JID& recipient, JingleSessionImpl::ref, const std::vector<JingleContentPayload::ref>& contents); private: IQRouter* router; JingleResponder* responder; std::vector<IncomingJingleSessionHandler*> incomingSessionHandlers; struct JIDSession { - JIDSession(const JID& jid, const std::string& session) : jid(jid), session(session) {} + JIDSession(const JID& initiator, const std::string& session) : initiator(initiator), session(session) {} bool operator<(const JIDSession& o) const { - return jid == o.jid ? session < o.session : jid < o.jid; + return initiator == o.initiator ? session < o.session : initiator < o.initiator; } - JID jid; + JID initiator; std::string session; }; - typedef std::map<JIDSession, JingleSession::ref> SessionMap; - SessionMap incomingSessions; + typedef std::map<JIDSession, JingleSessionImpl::ref> SessionMap; + SessionMap sessions; }; } diff --git a/Swiften/Jingle/SConscript b/Swiften/Jingle/SConscript index a8890b7..5dcf293 100644 --- a/Swiften/Jingle/SConscript +++ b/Swiften/Jingle/SConscript @@ -1,11 +1,12 @@ Import("swiften_env") sources = [ - "IncomingJingleSession.cpp", + "JingleSession.cpp", + "JingleSessionImpl.cpp", "IncomingJingleSessionHandler.cpp", "JingleSessionManager.cpp", "JingleResponder.cpp", - "JingleSession.cpp", + "FakeJingleSession.cpp", ] swiften_env.Append(SWIFTEN_OBJECTS = swiften_env.SwiftenObject(sources)) |