From 260262c393002041e5dbca789613e0184949df03 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sat, 1 Oct 2011 21:12:18 +0200 Subject: [PATCH] Move FT to separate class --- CMakeLists.txt | 2 +- backends/libpurple/main.cpp | 50 +++++++++++--- include/transport/filetransfermanager.h | 68 ++++++++++++++++++ include/transport/networkplugin.h | 4 ++ include/transport/networkpluginserver.h | 83 +++++++++++++--------- include/transport/user.h | 4 -- include/transport/usermanager.h | 26 ------- spectrum/src/main.cpp | 5 +- src/filetransfermanager.cpp | 91 +++++++++++++++++++++++++ src/networkplugin.cpp | 26 +++++++ src/networkpluginserver.cpp | 66 ++++++++++++++---- src/pbnetwork.proto | 2 + src/user.cpp | 15 ---- src/usermanager.cpp | 18 ----- 14 files changed, 339 insertions(+), 121 deletions(-) create mode 100644 include/transport/filetransfermanager.h create mode 100644 src/filetransfermanager.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cc976737..aa939f41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,7 +108,7 @@ else() endif() if(CMAKE_BUILD_TYPE MATCHES Debug) - ADD_DEFINITIONS(-O0) + ADD_DEFINITIONS(-O3) ADD_DEFINITIONS(-ggdb) ADD_DEFINITIONS(-DDEBUG) ADD_DEFINITIONS(-Wall) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index b597c6a4..2a499bf3 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -47,6 +47,11 @@ static int port = 10000; static gboolean ver = FALSE; static gboolean list_purple_settings = FALSE; +struct FTData { + unsigned long id; + bool paused; +}; + static GOptionEntry options_entries[] = { { "nodaemon", 'n', 0, G_OPTION_ARG_NONE, &nodaemon, "Disable background daemon mode", NULL }, { "logfile", 'l', 0, G_OPTION_ARG_STRING, &logfile, "Set file to log", NULL }, @@ -812,21 +817,41 @@ class SpectrumNetworkPlugin : public NetworkPlugin { } void handleFTStartRequest(const std::string &user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID) { - PurpleXfer *xfer = m_xfers[user + fileName + buddyName]; + PurpleXfer *xfer = m_unhandledXfers[user + fileName + buddyName]; if (xfer) { - xfer->ui_data = (void *) ftID; + m_unhandledXfers.erase(user + fileName + buddyName); + FTData *ftData = (FTData *) xfer->ui_data; + + ftData->id = ftID; + m_xfers[ftID] = xfer; purple_xfer_request_accepted(xfer, fileName.c_str()); purple_xfer_ui_ready(xfer); } } + void handleFTPauseRequest(unsigned long ftID) { + PurpleXfer *xfer = m_xfers[ftID]; + if (!xfer) + return; + FTData *ftData = (FTData *) xfer->ui_data; + ftData->paused = true; + } + + void handleFTContinueRequest(unsigned long ftID) { + PurpleXfer *xfer = m_xfers[ftID]; + if (!xfer) + return; + FTData *ftData = (FTData *) xfer->ui_data; + ftData->paused = false; + purple_xfer_ui_ready(xfer); + } + void readyForData() { if (m_waitingXfers.empty()) return; std::vector tmp; tmp.swap(m_waitingXfers); - LOG4CXX_INFO(logger, "readyForData " << tmp.size()); BOOST_FOREACH(PurpleXfer *xfer, tmp) { purple_xfer_ui_ready(xfer); } @@ -836,10 +861,10 @@ class SpectrumNetworkPlugin : public NetworkPlugin { std::map m_accounts; std::map m_vcards; std::map m_authRequests; - std::map m_xfers; + std::map m_xfers; + std::map m_unhandledXfers; std::vector m_waitingXfers; Config *config; - }; static bool getStatus(PurpleBuddy *m_buddy, Swift::StatusShow &status, std::string &statusMessage) { @@ -1344,7 +1369,11 @@ static void newXfer(PurpleXfer *xfer) { size_t pos = w.find("/"); if (pos != std::string::npos) w.erase((int) pos, w.length() - (int) pos); - np->m_xfers[np->m_accounts[account] + filename + w] = xfer; + + xfer->ui_data = (void *) new FTData; + + np->m_unhandledXfers[np->m_accounts[account] + filename + w] = xfer; + np->handleFTStart(np->m_accounts[account], w, filename, purple_xfer_get_size(xfer)); } @@ -1362,11 +1391,12 @@ static void XferSendComplete(PurpleXfer *xfer) { } static gssize XferWrite(PurpleXfer *xfer, const guchar *buffer, gssize size) { - LOG4CXX_INFO(logger, "before_xfer_write " << size); + FTData *ftData = (FTData *) xfer->ui_data; std::string data((const char *) buffer, (size_t) size); - np->m_waitingXfers.push_back(xfer); - np->handleFTData((unsigned long) xfer->ui_data, data); - LOG4CXX_INFO(logger, "xfer_write " << size); + if (ftData->paused) { + np->m_waitingXfers.push_back(xfer); + } + np->handleFTData(ftData->id, data); return size; } diff --git a/include/transport/filetransfermanager.h b/include/transport/filetransfermanager.h new file mode 100644 index 00000000..322962c5 --- /dev/null +++ b/include/transport/filetransfermanager.h @@ -0,0 +1,68 @@ +/** + * libtransport -- C++ library for easy XMPP Transports development + * + * Copyright (C) 2011, Jan Kaluza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Transport { + +class UserManager; +class User; +class Component; +class Buddy; + +class FileTransferManager { + public: + typedef struct Transfer { + boost::shared_ptr ft; + Swift::JID from; + Swift::JID to; + boost::shared_ptr readByteStream; + } Transfer; + + FileTransferManager(Component *component, UserManager *userManager); + virtual ~FileTransferManager(); + + FileTransferManager::Transfer sendFile(User *user, Buddy *buddy, boost::shared_ptr byteStream, const Swift::StreamInitiationFileInfo &info); + + private: + Component *m_component; + UserManager *m_userManager; + Swift::CombinedOutgoingFileTransferManager* m_outgoingFTManager; + Swift::RemoteJingleTransportCandidateSelectorFactory* m_remoteCandidateSelectorFactory; + Swift::LocalJingleTransportCandidateGeneratorFactory* m_localCandidateGeneratorFactory; + Swift::JingleSessionManager *m_jingleSessionManager; + Swift::SOCKS5BytestreamRegistry* m_bytestreamRegistry; + Swift::SOCKS5BytestreamServer* m_bytestreamServer; + Swift::SOCKS5BytestreamProxy* m_bytestreamProxy; + Swift::SOCKS5BytestreamServer *bytestreamServer; + Swift::ConnectivityManager* m_connectivityManager; +}; + +} diff --git a/include/transport/networkplugin.h b/include/transport/networkplugin.h index 9173714e..afbb310b 100644 --- a/include/transport/networkplugin.h +++ b/include/transport/networkplugin.h @@ -216,6 +216,8 @@ class NetworkPlugin { virtual void handleAttentionRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*message*/) {} virtual void handleFTStartRequest(const std::string &/*user*/, const std::string &/*buddyName*/, const std::string &/*fileName*/, unsigned long size, unsigned long ftID) {} + virtual void handleFTPauseRequest(unsigned long ftID) {} + virtual void handleFTContinueRequest(unsigned long ftID) {} virtual void handleExit() { std::cout << "EXITING\n"; exit(1); } @@ -234,6 +236,8 @@ class NetworkPlugin { void handleChatStatePayload(const std::string &payload, Swift::ChatState::ChatStateType type); void handleAttentionPayload(const std::string &payload); void handleFTStartPayload(const std::string &payload); + void handleFTPausePayload(const std::string &payload); + void handleFTContinuePayload(const std::string &payload); void handleDataRead(boost::shared_ptr data); void _handleConnected(bool error); void handleDisconnected(); diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index b7ca5f29..468dc89b 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -27,6 +27,7 @@ #include "Swiften/Network/BoostConnectionServer.h" #include "Swiften/Network/Connection.h" #include "storagebackend.h" +#include "transport/filetransfermanager.h" namespace Transport { @@ -40,35 +41,7 @@ class NetworkConversation; class VCardResponder; class RosterResponder; class BlockResponder; - -class DummyReadBytestream : public Swift::ReadBytestream { - public: - DummyReadBytestream() {m_finished = false;} - virtual ~DummyReadBytestream() {} - void appendData(const std::string &data) { - m_data += data; - onDataAvailable(); - } - - virtual std::vector read(size_t size) { - if (m_data.empty()) { - return std::vector(); - } - - if (m_data.size() < size) { - m_finished = true; - return std::vector(m_data.begin(), m_data.end()); - } - std::string ret = m_data.substr(0, size); - m_data.erase(m_data.begin(), m_data.begin() + size); - return std::vector(ret.begin(), ret.end()); - } - virtual bool isFinished() const { return m_finished; } - - private: - bool m_finished; - std::string m_data; -}; +class DummyReadBytestream; class NetworkPluginServer { public: @@ -84,7 +57,7 @@ class NetworkPluginServer { bool longRun; }; - NetworkPluginServer(Component *component, Config *config, UserManager *userManager); + NetworkPluginServer(Component *component, Config *config, UserManager *userManager, FileTransferManager *ftManager); virtual ~NetworkPluginServer(); @@ -119,7 +92,7 @@ class NetworkPluginServer { void handleAttentionPayload(const std::string &payload); void handleStatsPayload(Backend *c, const std::string &payload); void handleFTStartPayload(const std::string &payload); - void handleFTDataPayload(const std::string &payload); + void handleFTDataPayload(Backend *b ,const std::string &payload); void handleUserCreated(User *user); void handleRoomJoined(User *user, const std::string &room, const std::string &nickname, const std::string &password); @@ -137,8 +110,10 @@ class NetworkPluginServer { void handleVCardUpdated(User *user, boost::shared_ptr vcard); void handleVCardRequired(User *user, const std::string &name, unsigned int id); + void handleFTStateChanged(Swift::FileTransfer::State state, const std::string &userName, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long id); void handleFTAccepted(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID); - void handleFTRejected(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID); + void handleFTRejected(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size); + void handleFTDataNeeded(Backend *b, unsigned long ftid); void send(boost::shared_ptr &, const std::string &data); @@ -158,7 +133,49 @@ class NetworkPluginServer { Component *m_component; std::list m_waitingUsers; bool m_isNextLongRun; - std::map > m_bytestreams; + std::map m_filetransfers; + FileTransferManager *m_ftManager; +}; + +class DummyReadBytestream : public Swift::ReadBytestream { + public: + DummyReadBytestream(NetworkPluginServer::Backend *b, unsigned long ftid) {neededData = false; m_finished = false; this->b = b; this->ftid = ftid;} + virtual ~DummyReadBytestream() {} + unsigned long appendData(const std::string &data) { + m_data += data; + onDataAvailable(); + neededData = false; + return m_data.size(); + } + + virtual boost::shared_ptr > read(size_t size) { + if (m_data.empty()) { + return boost::shared_ptr >(new std::vector()); + } + + if (m_data.size() < size) { + boost::shared_ptr > ptr(new std::vector(m_data.begin(), m_data.end())); + m_data.clear(); + onDataNeeded(b, ftid); + return ptr; + } + boost::shared_ptr > ptr(new std::vector(m_data.begin(), m_data.begin() + size)); + m_data.erase(m_data.begin(), m_data.begin() + size); + if (m_data.size() < 500000 && !neededData) { + neededData = true; + onDataNeeded(b, ftid); + } + return ptr; + } + boost::signal onDataNeeded; + virtual bool isFinished() const { return m_finished; } + + private: + bool m_finished; + NetworkPluginServer::Backend *b; + unsigned long ftid; + std::string m_data; + bool neededData; }; } diff --git a/include/transport/user.h b/include/transport/user.h index 76cf5df6..fe06277a 100644 --- a/include/transport/user.h +++ b/include/transport/user.h @@ -109,18 +109,14 @@ class User : public Swift::EntityCapsProvider { return m_connected; } - void sendFile(const Swift::JID& from, boost::shared_ptr byteStream, const Swift::StreamInitiationFileInfo &info, unsigned long id); - boost::signal onReadyToConnect; boost::signal onPresenceChanged; boost::signal onRoomJoined; boost::signal onRoomLeft; boost::signal onDisconnected; - boost::signal onFTAccepted; private: void onConnectingTimeout(); - void handleFTStateChanged(Swift::FileTransfer::State state, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long id); Swift::JID m_jid; Component *m_component; diff --git a/include/transport/usermanager.h b/include/transport/usermanager.h index ae26dd57..cd02aade 100644 --- a/include/transport/usermanager.h +++ b/include/transport/usermanager.h @@ -25,17 +25,6 @@ #include "Swiften/Swiften.h" #include "transport/userregistry.h" -// FT STUFF TODO: move me -#include -#include -#include -#include -#include -#include -#include -#include -#include - namespace Transport { class User; @@ -123,10 +112,6 @@ class UserManager : public Swift::EntityCapsProvider { /// \param user JID of user. void disconnectUser(const Swift::JID &user); - Swift::CombinedOutgoingFileTransferManager *getOutgoingFileTransferManager() { - return m_outgoingFTManager; - } - private: void handlePresence(Swift::Presence::ref presence); void handleMessageReceived(Swift::Message::ref message); @@ -146,17 +131,6 @@ class UserManager : public Swift::EntityCapsProvider { UserRegistry *m_userRegistry; Swift::Timer::ref m_removeTimer; friend class RosterResponder; - - // FT stuff TODO: move to separate class once we will now what will be here - Swift::CombinedOutgoingFileTransferManager* m_outgoingFTManager; - Swift::RemoteJingleTransportCandidateSelectorFactory* m_remoteCandidateSelectorFactory; - Swift::LocalJingleTransportCandidateGeneratorFactory* m_localCandidateGeneratorFactory; - Swift::JingleSessionManager *m_jingleSessionManager; - Swift::SOCKS5BytestreamRegistry* m_bytestreamRegistry; - Swift::SOCKS5BytestreamServer* m_bytestreamServer; - Swift::SOCKS5BytestreamProxy* m_bytestreamProxy; - Swift::SOCKS5BytestreamServer *bytestreamServer; - Swift::ConnectivityManager* m_connectivityManager; }; } diff --git a/spectrum/src/main.cpp b/spectrum/src/main.cpp index 4ceb1bb4..29949534 100644 --- a/spectrum/src/main.cpp +++ b/spectrum/src/main.cpp @@ -1,5 +1,6 @@ #include "transport/config.h" #include "transport/transport.h" +#include "transport/filetransfermanager.h" #include "transport/usermanager.h" #include "transport/logger.h" #include "transport/sqlite3backend.h" @@ -288,7 +289,9 @@ int main(int argc, char **argv) } // logger.setUserManager(&userManager); - NetworkPluginServer plugin(&transport, &config, &userManager); + FileTransferManager ftManager(&transport, &userManager); + + NetworkPluginServer plugin(&transport, &config, &userManager, &ftManager); AdminInterface adminInterface(&transport, &userManager, &plugin, storageBackend); diff --git a/src/filetransfermanager.cpp b/src/filetransfermanager.cpp new file mode 100644 index 00000000..dca8c6d6 --- /dev/null +++ b/src/filetransfermanager.cpp @@ -0,0 +1,91 @@ +/** + * libtransport -- C++ library for easy XMPP Transports development + * + * Copyright (C) 2011, Jan Kaluza + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + +#include "transport/filetransfermanager.h" +#include "transport/transport.h" +#include "transport/usermanager.h" +#include "transport/user.h" +#include "transport/buddy.h" +#include "log4cxx/logger.h" + +using namespace log4cxx; + +namespace Transport { + +static LoggerPtr logger = Logger::getLogger("FileTransferManager"); + +FileTransferManager::FileTransferManager(Component *component, UserManager *userManager) { + m_component = component; + m_userManager = userManager; + + m_jingleSessionManager = new Swift::JingleSessionManager(m_component->getIQRouter()); + m_connectivityManager = new Swift::ConnectivityManager(m_component->getNetworkFactories()->getNATTraverser()); + m_bytestreamRegistry = new Swift::SOCKS5BytestreamRegistry(); + m_bytestreamProxy = new Swift::SOCKS5BytestreamProxy(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory()); + + m_localCandidateGeneratorFactory = new Swift::DefaultLocalJingleTransportCandidateGeneratorFactory(m_connectivityManager, m_bytestreamRegistry, m_bytestreamProxy, "thishouldnotbeused"); + m_remoteCandidateSelectorFactory = new Swift::DefaultRemoteJingleTransportCandidateSelectorFactory(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory()); + + boost::shared_ptr server = m_component->getNetworkFactories()->getConnectionServerFactory()->createConnectionServer(19645); + server->start(); + m_bytestreamServer = new Swift::SOCKS5BytestreamServer(server, m_bytestreamRegistry); + m_bytestreamServer->start(); + + m_outgoingFTManager = new Swift::CombinedOutgoingFileTransferManager(m_jingleSessionManager, m_component->getIQRouter(), + m_userManager, m_remoteCandidateSelectorFactory, + m_localCandidateGeneratorFactory, m_bytestreamRegistry, + m_bytestreamProxy, m_component->getPresenceOracle(), + m_bytestreamServer); + +// WARNING: Swiften crashes when this is uncommented... But we probably need it for working Jingle FT +// m_connectivityManager->addListeningPort(19645); +} + +FileTransferManager::~FileTransferManager() { + m_bytestreamServer->stop(); + delete m_outgoingFTManager; + delete m_remoteCandidateSelectorFactory; + delete m_localCandidateGeneratorFactory; + delete m_jingleSessionManager; + delete m_bytestreamRegistry; + delete m_bytestreamServer; + delete m_bytestreamProxy; + delete bytestreamServer; + delete m_connectivityManager; +} + +FileTransferManager::Transfer FileTransferManager::sendFile(User *user, Buddy *buddy, boost::shared_ptr byteStream, const Swift::StreamInitiationFileInfo &info) { + FileTransferManager::Transfer transfer; + transfer.from = buddy->getJID(); + transfer.to = user->getJID(); + transfer.readByteStream = byteStream; + + LOG4CXX_INFO(logger, "Starting FT from '" << transfer.from << "' to '" << transfer.to << "'") + + transfer.ft = m_outgoingFTManager->createOutgoingFileTransfer(transfer.from, transfer.to, transfer.readByteStream, info); +// if (transfer.ft) { +// m_filetransfers.push_back(ft); +// ft->onStateChange.connect(boost::bind(&User::handleFTStateChanged, this, _1, Buddy::JIDToLegacyName(from), info.getName(), info.getSize(), id)); +// transfer.ft->start(); +// } + return transfer; +} + +} diff --git a/src/networkplugin.cpp b/src/networkplugin.cpp index 2aa5ce7a..86ae3bd5 100644 --- a/src/networkplugin.cpp +++ b/src/networkplugin.cpp @@ -373,6 +373,26 @@ void NetworkPlugin::handleFTStartPayload(const std::string &data) { handleFTStartRequest(payload.username(), payload.buddyname(), payload.filename(), payload.size(), payload.ftid()); } +void NetworkPlugin::handleFTPausePayload(const std::string &data) { + pbnetwork::FileTransferData payload; + if (payload.ParseFromString(data) == false) { + // TODO: ERROR + return; + } + + handleFTPauseRequest(payload.ftid()); +} + +void NetworkPlugin::handleFTContinuePayload(const std::string &data) { + pbnetwork::FileTransferData payload; + if (payload.ParseFromString(data) == false) { + // TODO: ERROR + return; + } + + handleFTContinueRequest(payload.ftid()); +} + void NetworkPlugin::handleJoinRoomPayload(const std::string &data) { pbnetwork::Room payload; if (payload.ParseFromString(data) == false) { @@ -523,6 +543,12 @@ void NetworkPlugin::handleDataRead(boost::shared_ptr data) case pbnetwork::WrapperMessage_Type_TYPE_FT_START: handleFTStartPayload(wrapper.payload()); break; + case pbnetwork::WrapperMessage_Type_TYPE_FT_PAUSE: + handleFTPausePayload(wrapper.payload()); + break; + case pbnetwork::WrapperMessage_Type_TYPE_FT_CONTINUE: + handleFTContinuePayload(wrapper.payload()); + break; default: return; } diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 69edf1a3..a1d40d0b 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -207,8 +207,8 @@ static void handleBuddyPayload(LocalBuddy *buddy, const pbnetwork::Buddy &payloa buddy->setBlocked(payload.blocked()); } -NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, UserManager *userManager) { - std::cout << "BUDDY " << sizeof(LocalBuddy) << "\n"; +NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, UserManager *userManager, FileTransferManager *ftManager) { + m_ftManager = ftManager; m_userManager = userManager; m_config = config; m_component = component; @@ -599,17 +599,24 @@ void NetworkPluginServer::handleFTStartPayload(const std::string &data) { fileInfo.setSize(payload.size()); fileInfo.setName(payload.filename()); - boost::shared_ptr bytestream(new DummyReadBytestream()); + Backend *c = (Backend *) user->getData(); + boost::shared_ptr bytestream(new DummyReadBytestream(c, bytestream_id + 1)); + bytestream->onDataNeeded.connect(boost::bind(&NetworkPluginServer::handleFTDataNeeded, this, _1, _2)); LOG4CXX_INFO(logger, "jid=" << buddy->getJID()); - m_bytestreams[++bytestream_id] = bytestream; + FileTransferManager::Transfer transfer = m_ftManager->sendFile(user, buddy, bytestream, fileInfo); + if (!transfer.ft) { + handleFTRejected(user, payload.buddyname(), payload.filename(), payload.size()); + return; + } - user->sendFile(buddy->getJID(), bytestream, fileInfo, bytestream_id); -// handleFTAccepted(user, payload.buddyname(), payload.filename(), payload.size()); + m_filetransfers[++bytestream_id] = transfer; + transfer.ft->onStateChange.connect(boost::bind(&NetworkPluginServer::handleFTStateChanged, this, _1, payload.username(), payload.buddyname(), payload.filename(), payload.size(), bytestream_id)); + transfer.ft->start(); } -void NetworkPluginServer::handleFTDataPayload(const std::string &data) { +void NetworkPluginServer::handleFTDataPayload(Backend *b, const std::string &data) { pbnetwork::FileTransferData payload; if (payload.ParseFromString(data) == false) { // TODO: ERROR @@ -620,9 +627,34 @@ void NetworkPluginServer::handleFTDataPayload(const std::string &data) { // if (!user) // return; - m_bytestreams[payload.ftid()]->appendData(payload.data()); + FileTransferManager::Transfer &transfer = m_filetransfers[payload.ftid()]; + DummyReadBytestream *bytestream = (DummyReadBytestream *) transfer.readByteStream.get(); - LOG4CXX_INFO(logger, "handleFTDataPayload size=" << payload.data().size()); + if (bytestream->appendData(payload.data()) > 5000000) { + pbnetwork::FileTransferData f; + f.set_ftid(payload.ftid()); + f.set_data(""); + + std::string message; + f.SerializeToString(&message); + + WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_FT_PAUSE); + + send(b->connection, message); + } +} + +void NetworkPluginServer::handleFTDataNeeded(Backend *b, unsigned long ftid) { + pbnetwork::FileTransferData f; + f.set_ftid(ftid); + f.set_data(""); + + std::string message; + f.SerializeToString(&message); + + WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_FT_CONTINUE); + + send(b->connection, message); } void NetworkPluginServer::handleDataRead(Backend *c, boost::shared_ptr data) { @@ -708,7 +740,7 @@ void NetworkPluginServer::handleDataRead(Backend *c, boost::shared_ptronPresenceChanged.connect(boost::bind(&NetworkPluginServer::handleUserPresenceChanged, this, user, _1)); user->onRoomJoined.connect(boost::bind(&NetworkPluginServer::handleRoomJoined, this, user, _1, _2, _3)); user->onRoomLeft.connect(boost::bind(&NetworkPluginServer::handleRoomLeft, this, user, _1)); - user->onFTAccepted.connect(boost::bind(&NetworkPluginServer::handleFTAccepted, this, user, _1, _2, _3, _4)); } void NetworkPluginServer::handleUserReadyToConnect(User *user) { @@ -1215,13 +1246,12 @@ void NetworkPluginServer::handleFTAccepted(User *user, const std::string &buddyN send(c->connection, message); } -void NetworkPluginServer::handleFTRejected(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID) { +void NetworkPluginServer::handleFTRejected(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size) { pbnetwork::File f; f.set_username(user->getJID().toBare()); f.set_buddyname(buddyName); f.set_filename(fileName); f.set_size(size); - f.set_ftid(ftID); std::string message; f.SerializeToString(&message); @@ -1235,6 +1265,16 @@ void NetworkPluginServer::handleFTRejected(User *user, const std::string &buddyN send(c->connection, message); } +void NetworkPluginServer::handleFTStateChanged(Swift::FileTransfer::State state, const std::string &userName, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long id) { + User *user = m_userManager->getUser(userName); + if (!user) { + // TODO: reject and remove filetransfer + } + if (state.state == Swift::FileTransfer::State::Transferring) { + handleFTAccepted(user, buddyName, fileName, size, id); + } +} + void NetworkPluginServer::sendPing(Backend *c) { std::string message; diff --git a/src/pbnetwork.proto b/src/pbnetwork.proto index 1bfaad37..a492feb2 100644 --- a/src/pbnetwork.proto +++ b/src/pbnetwork.proto @@ -128,6 +128,8 @@ message WrapperMessage { TYPE_FT_START = 24; TYPE_FT_FINISH = 25; TYPE_FT_DATA = 26; + TYPE_FT_PAUSE = 27; + TYPE_FT_CONTINUE = 28; } required Type type = 1; optional bytes payload = 2; diff --git a/src/user.cpp b/src/user.cpp index 5e66268a..2cf74cbd 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -309,19 +309,4 @@ void User::handleDisconnected(const std::string &error) { } } -void User::handleFTStateChanged(Swift::FileTransfer::State state, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long id) { - if (state.state == Swift::FileTransfer::State::Transferring) { - onFTAccepted(buddyName, fileName, size, id); - } -} - -void User::sendFile(const Swift::JID& from, boost::shared_ptr byteStream, const Swift::StreamInitiationFileInfo &info, unsigned long id) { - boost::shared_ptr ft = m_userManager->getOutgoingFileTransferManager()->createOutgoingFileTransfer(from, m_jid, byteStream, info); - if (ft) { - m_filetransfers.push_back(ft); - ft->onStateChange.connect(boost::bind(&User::handleFTStateChanged, this, _1, Buddy::JIDToLegacyName(from), info.getName(), info.getSize(), id)); - ft->start(); - } -} - } diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 2b21cb46..6110c45e 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -61,24 +61,6 @@ UserManager::UserManager(Component *component, UserRegistry *userRegistry, Stora m_userRegistry->onDisconnectUser.connect(bind(&UserManager::disconnectUser, this, _1)); m_removeTimer = m_component->getNetworkFactories()->getTimerFactory()->createTimer(1); - - // FT STUFF - m_jingleSessionManager = new Swift::JingleSessionManager(m_component->getIQRouter()); - m_connectivityManager = new Swift::ConnectivityManager(m_component->getNetworkFactories()->getNATTraverser()); - m_bytestreamRegistry = new Swift::SOCKS5BytestreamRegistry(); - m_bytestreamProxy = new Swift::SOCKS5BytestreamProxy(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory()); - - m_localCandidateGeneratorFactory = new Swift::DefaultLocalJingleTransportCandidateGeneratorFactory(m_connectivityManager, m_bytestreamRegistry, m_bytestreamProxy, "thishouldnotbeused"); - m_remoteCandidateSelectorFactory = new Swift::DefaultRemoteJingleTransportCandidateSelectorFactory(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory()); - - boost::shared_ptr server = m_component->getNetworkFactories()->getConnectionServerFactory()->createConnectionServer(19645); - server->start(); - bytestreamServer = new Swift::SOCKS5BytestreamServer(server, m_bytestreamRegistry); - bytestreamServer->start(); - - m_outgoingFTManager = new Swift::CombinedOutgoingFileTransferManager(m_jingleSessionManager, m_component->getIQRouter(), this, m_remoteCandidateSelectorFactory, m_localCandidateGeneratorFactory, m_bytestreamRegistry, m_bytestreamProxy, m_component->getPresenceOracle(), bytestreamServer); - -// m_connectivityManager->addListeningPort(19645); } UserManager::~UserManager(){