From 88b7dd86b2bea417a0ac06d255fe77fae8d675ae Mon Sep 17 00:00:00 2001 From: HanzZ Date: Fri, 30 Sep 2011 10:01:51 +0200 Subject: [PATCH] Added missing files --- .../CombinedOutgoingFileTransferManager.cpp | 109 ++++++++++++++++++ .../CombinedOutgoingFileTransferManager.h | 53 +++++++++ .../FileTransfer/MyOutgoingSIFileTransfer.cpp | 90 +++++++++++++++ .../FileTransfer/MyOutgoingSIFileTransfer.h | 56 +++++++++ 4 files changed, 308 insertions(+) create mode 100644 include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.cpp create mode 100644 include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h create mode 100644 include/Swiften/FileTransfer/MyOutgoingSIFileTransfer.cpp create mode 100644 include/Swiften/FileTransfer/MyOutgoingSIFileTransfer.h diff --git a/include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.cpp b/include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.cpp new file mode 100644 index 00000000..710b8f83 --- /dev/null +++ b/include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "CombinedOutgoingFileTransferManager.h" + +#include + +#include +#include "Swiften/Disco/EntityCapsProvider.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Swift { + +CombinedOutgoingFileTransferManager::CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, PresenceOracle *presOracle, SOCKS5BytestreamServer *bytestreamServer) : jsManager(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), presenceOracle(presOracle), bytestreamServer(bytestreamServer) { + idGenerator = new IDGenerator(); +} + +CombinedOutgoingFileTransferManager::~CombinedOutgoingFileTransferManager() { + delete idGenerator; +} + +boost::shared_ptr CombinedOutgoingFileTransferManager::createOutgoingFileTransfer(const JID& from, const JID& receipient, boost::shared_ptr readBytestream, const StreamInitiationFileInfo& fileInfo) { + // check if receipient support Jingle FT + boost::optional fullJID = highestPriorityJIDSupportingJingle(receipient); + if (!fullJID.is_initialized()) { + fullJID = highestPriorityJIDSupportingSI(receipient); + } + else { + JingleSessionImpl::ref jingleSession = boost::make_shared(from, receipient, idGenerator->generateID(), iqRouter); + + //jsManager->getSession(receipient, idGenerator->generateID()); + assert(jingleSession); + jsManager->registerOutgoingSession(from, jingleSession); + boost::shared_ptr jingleFT = boost::shared_ptr(new OutgoingJingleFileTransfer(jingleSession, remoteFactory, localFactory, iqRouter, idGenerator, from, receipient, readBytestream, fileInfo, bytestreamRegistry, bytestreamProxy)); + return jingleFT; + } + + if (!fullJID.is_initialized()) { + return boost::shared_ptr(); + } + + // otherwise try SI + boost::shared_ptr jingleFT = boost::shared_ptr(new MyOutgoingSIFileTransfer(idGenerator->generateID(), from, fullJID.get(), fileInfo.getName(), fileInfo.getSize(), fileInfo.getDescription(), readBytestream, iqRouter, bytestreamServer, bytestreamRegistry)); + // else fail + + return jingleFT; +} + +boost::optional CombinedOutgoingFileTransferManager::highestPriorityJIDSupportingJingle(const JID& bareJID) { + JID fullReceipientJID; + int priority = INT_MIN; + + //getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11 + std::vector presences = presenceOracle->getAllPresence(bareJID); + + //iterate over them + foreach(Presence::ref pres, presences) { + if (pres->getPriority() > priority) { + // look up caps from the jid + DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom()); + if (info && info->hasFeature(DiscoInfo::JingleFeature) && info->hasFeature(DiscoInfo::JingleFTFeature) && + info->hasFeature(DiscoInfo::JingleTransportsIBBFeature)) { + + priority = pres->getPriority(); + fullReceipientJID = pres->getFrom(); + } + } + } + + return fullReceipientJID.isValid() ? boost::optional(fullReceipientJID) : boost::optional(); +} + +boost::optional CombinedOutgoingFileTransferManager::highestPriorityJIDSupportingSI(const JID& bareJID) { + JID fullReceipientJID; + int priority = INT_MIN; + + //getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11 + std::vector presences = presenceOracle->getAllPresence(bareJID); + + //iterate over them + foreach(Presence::ref pres, presences) { + if (pres->getPriority() > priority) { + // look up caps from the jid + DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom()); + if (info && info->hasFeature("http://jabber.org/protocol/si/profile/file-transfer")) { + + priority = pres->getPriority(); + fullReceipientJID = pres->getFrom(); + } + } + } + + return fullReceipientJID.isValid() ? boost::optional(fullReceipientJID) : boost::optional(); +} + +} diff --git a/include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h b/include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h new file mode 100644 index 00000000..765e6ba2 --- /dev/null +++ b/include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include +#include + +#include + +namespace Swift { + +class JingleSessionManager; +class IQRouter; +class EntityCapsProvider; +class RemoteJingleTransportCandidateSelectorFactory; +class LocalJingleTransportCandidateGeneratorFactory; +class OutgoingFileTransfer; +class JID; +class IDGenerator; +class ReadBytestream; +class StreamInitiationFileInfo; +class SOCKS5BytestreamRegistry; +class SOCKS5BytestreamProxy; +class SOCKS5BytestreamServer; +class PresenceOracle; + +class CombinedOutgoingFileTransferManager { +public: + CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, PresenceOracle* presOracle, SOCKS5BytestreamServer *server); + ~CombinedOutgoingFileTransferManager(); + + boost::shared_ptr createOutgoingFileTransfer(const JID& from, const JID& to, boost::shared_ptr, const StreamInitiationFileInfo&); + +private: + boost::optional highestPriorityJIDSupportingJingle(const JID& bareJID); + boost::optional highestPriorityJIDSupportingSI(const JID& bareJID); + JingleSessionManager* jsManager; + IQRouter* iqRouter; + EntityCapsProvider* capsProvider; + RemoteJingleTransportCandidateSelectorFactory* remoteFactory; + LocalJingleTransportCandidateGeneratorFactory* localFactory; + IDGenerator *idGenerator; + SOCKS5BytestreamRegistry* bytestreamRegistry; + SOCKS5BytestreamProxy* bytestreamProxy; + PresenceOracle* presenceOracle; + SOCKS5BytestreamServer *bytestreamServer; +}; + +} diff --git a/include/Swiften/FileTransfer/MyOutgoingSIFileTransfer.cpp b/include/Swiften/FileTransfer/MyOutgoingSIFileTransfer.cpp new file mode 100644 index 00000000..6593a238 --- /dev/null +++ b/include/Swiften/FileTransfer/MyOutgoingSIFileTransfer.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include + +#include + +#include +#include +#include +#include +#include + +namespace Swift { + +MyOutgoingSIFileTransfer::MyOutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer, SOCKS5BytestreamRegistry* registry) : id(id), from(from), to(to), name(name), size(size), description(description), bytestream(bytestream), iqRouter(iqRouter), socksServer(socksServer), registry(registry) { +} + +void MyOutgoingSIFileTransfer::start() { + StreamInitiation::ref streamInitiation(new StreamInitiation()); + streamInitiation->setID(id); + streamInitiation->setFileInfo(StreamInitiationFileInfo(name, description, size)); + streamInitiation->addProvidedMethod("http://jabber.org/protocol/bytestreams"); + streamInitiation->addProvidedMethod("http://jabber.org/protocol/ibb"); + StreamInitiationRequest::ref request = StreamInitiationRequest::create(from, to, streamInitiation, iqRouter); + request->onResponse.connect(boost::bind(&MyOutgoingSIFileTransfer::handleStreamInitiationRequestResponse, this, _1, _2)); + request->send(); +} + +void MyOutgoingSIFileTransfer::stop() { +} + +void MyOutgoingSIFileTransfer::handleStreamInitiationRequestResponse(StreamInitiation::ref response, ErrorPayload::ref error) { + if (error) { + finish(FileTransferError()); + } + else { + if (response->getRequestedMethod() == "http://jabber.org/protocol/bytestreams") { + registry->addReadBytestream(SOCKS5BytestreamRegistry::getHostname(id, from, to), bytestream); + socksServer->addReadBytestream(id, from, to, bytestream); + Bytestreams::ref bytestreams(new Bytestreams()); + bytestreams->setStreamID(id); + HostAddressPort addressPort = socksServer->getAddressPort(); + bytestreams->addStreamHost(Bytestreams::StreamHost(addressPort.getAddress().toString(), from, addressPort.getPort())); + BytestreamsRequest::ref request = BytestreamsRequest::create(from, to, bytestreams, iqRouter); + request->onResponse.connect(boost::bind(&MyOutgoingSIFileTransfer::handleBytestreamsRequestResponse, this, _1, _2)); + request->send(); + } + else if (response->getRequestedMethod() == "http://jabber.org/protocol/ibb") { + ibbSession = boost::shared_ptr(new IBBSendSession(id, from, to, bytestream, iqRouter)); + ibbSession->onFinished.connect(boost::bind(&MyOutgoingSIFileTransfer::handleIBBSessionFinished, this, _1)); + ibbSession->start(); + + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + } + } +} + +void MyOutgoingSIFileTransfer::handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref error) { + if (error) { + finish(FileTransferError()); + return; + } + + SOCKS5BytestreamServerSession *serverSession = registry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(id, from, to)); +// serverSession->onBytesSent.connect(boost::bind(boost::ref(onProcessedBytes), _1)); +// serverSession->onFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransferFinished, this, _1)); + serverSession->startTransfer(); + onStateChange(FileTransfer::State(FileTransfer::State::Transferring)); + + //socksServer->onTransferFinished.connect(); +} + +void MyOutgoingSIFileTransfer::finish(boost::optional error) { + if (ibbSession) { + ibbSession->onFinished.disconnect(boost::bind(&MyOutgoingSIFileTransfer::handleIBBSessionFinished, this, _1)); + ibbSession.reset(); + } + socksServer->removeReadBytestream(id, from, to); + onFinished(error); +} + +void MyOutgoingSIFileTransfer::handleIBBSessionFinished(boost::optional error) { + finish(error); +} + +} diff --git a/include/Swiften/FileTransfer/MyOutgoingSIFileTransfer.h b/include/Swiften/FileTransfer/MyOutgoingSIFileTransfer.h new file mode 100644 index 00000000..8ab87243 --- /dev/null +++ b/include/Swiften/FileTransfer/MyOutgoingSIFileTransfer.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Swift { + class IQRouter; + class SOCKS5BytestreamServer; + class SOCKS5BytestreamRegistry; + + class MyOutgoingSIFileTransfer : public OutgoingFileTransfer { + public: + MyOutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer, SOCKS5BytestreamRegistry* registry); + + virtual void start(); + virtual void stop(); + virtual void cancel() {} + + boost::signal&)> onFinished; + + private: + void handleStreamInitiationRequestResponse(StreamInitiation::ref, ErrorPayload::ref); + void handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref); + void finish(boost::optional error); + void handleIBBSessionFinished(boost::optional error); + + private: + std::string id; + JID from; + JID to; + std::string name; + int size; + std::string description; + boost::shared_ptr bytestream; + IQRouter* iqRouter; + SOCKS5BytestreamServer* socksServer; + boost::shared_ptr ibbSession; + SOCKS5BytestreamRegistry *registry; + }; +}