diff --git a/include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.cpp b/include/Swiften/FileTransfer/CombinedOutgoingFileTransferManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..710b8f830b2ac3b4c6ead9f4e3375b9802bc5092 --- /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(); +} + +}