/* * Copyright (c) 2011 Tobias Markmann * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* * Copyright (c) 2013 Remko Tronçon * Licensed under the GNU General Public License. * See the COPYING file for more information. */ #include #include #include #include #include #include #include #include "Swiften/Disco/EntityCapsProvider.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Swift { FileTransferManagerImpl::FileTransferManagerImpl( const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, PresenceOracle* presOracle, ConnectionFactory* connectionFactory, ConnectionServerFactory* connectionServerFactory, TimerFactory* timerFactory, NetworkEnvironment* networkEnvironment, NATTraverser* natTraverser, CryptoProvider* crypto) : ownJID(ownFullJID), iqRouter(router), capsProvider(capsProvider), presenceOracle(presOracle) { assert(!ownFullJID.isBare()); bytestreamRegistry = new SOCKS5BytestreamRegistry(); s5bServerManager = new SOCKS5BytestreamServerManager( bytestreamRegistry, connectionServerFactory, networkEnvironment, natTraverser); bytestreamProxy = new SOCKS5BytestreamProxiesManager(connectionFactory, timerFactory); transporterFactory = new DefaultFileTransferTransporterFactory( bytestreamRegistry, s5bServerManager, bytestreamProxy, &idGenerator, connectionFactory, timerFactory, crypto, iqRouter); outgoingFTManager = new OutgoingFileTransferManager( jingleSessionManager, iqRouter, transporterFactory, crypto); incomingFTManager = new IncomingFileTransferManager( jingleSessionManager, iqRouter, transporterFactory, timerFactory, crypto); incomingFTManager->onIncomingFileTransfer.connect(onIncomingFileTransfer); } FileTransferManagerImpl::~FileTransferManagerImpl() { delete s5bServerManager; delete incomingFTManager; delete outgoingFTManager; delete transporterFactory; } void FileTransferManagerImpl::start() { } void FileTransferManagerImpl::stop() { s5bServerManager->stop(); } boost::optional FileTransferManagerImpl::highestPriorityJIDSupportingFileTransfer(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 (isSupportedBy(info)) { priority = pres->getPriority(); fullReceipientJID = pres->getFrom(); } } } return fullReceipientJID.isValid() ? boost::optional(fullReceipientJID) : boost::optional(); } OutgoingFileTransfer::ref FileTransferManagerImpl::createOutgoingFileTransfer( const JID& to, const boost::filesystem::path& filepath, const std::string& description, boost::shared_ptr bytestream, const FileTransferOptions& config) { #if BOOST_FILESYSTEM_VERSION == 2 // TODO: Delete this when boost 1.44 becomes a minimum requirement, and we no longer need v2 std::string filename = filepath.filename(); #else std::string filename = pathToString(filepath.filename()); #endif boost::uintmax_t sizeInBytes = boost::filesystem::file_size(filepath); boost::posix_time::ptime lastModified = boost::posix_time::from_time_t(boost::filesystem::last_write_time(filepath)); return createOutgoingFileTransfer(to, filename, description, sizeInBytes, lastModified, bytestream, config); } OutgoingFileTransfer::ref FileTransferManagerImpl::createOutgoingFileTransfer( const JID& to, const std::string& filename, const std::string& description, const boost::uintmax_t sizeInBytes, const boost::posix_time::ptime& lastModified, boost::shared_ptr bytestream, const FileTransferOptions& config) { StreamInitiationFileInfo fileInfo; fileInfo.setDate(lastModified); fileInfo.setSize(sizeInBytes); fileInfo.setName(filename); fileInfo.setDescription(description); JID receipient = to; if(receipient.isBare()) { boost::optional fullJID = highestPriorityJIDSupportingFileTransfer(receipient); if (fullJID.is_initialized()) { receipient = fullJID.get(); } else { return OutgoingFileTransfer::ref(); } } return outgoingFTManager->createOutgoingFileTransfer(ownJID, receipient, bytestream, fileInfo, config); } }