Move FT to separate class

This commit is contained in:
HanzZ 2011-10-01 21:12:18 +02:00
parent 88b7dd86b2
commit 260262c393
14 changed files with 339 additions and 121 deletions

View file

@ -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)

View file

@ -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<PurpleXfer *> 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<PurpleAccount *, std::string> m_accounts;
std::map<std::string, unsigned int> m_vcards;
std::map<std::string, authRequest *> m_authRequests;
std::map<std::string, PurpleXfer *> m_xfers;
std::map<unsigned long, PurpleXfer *> m_xfers;
std::map<std::string, PurpleXfer *> m_unhandledXfers;
std::vector<PurpleXfer *> 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;
}

View file

@ -0,0 +1,68 @@
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* 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 <Swiften/Elements/StreamInitiationFileInfo.h>
#include <Swiften/FileTransfer/ConnectivityManager.h>
#include <Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h>
#include <Swiften/FileTransfer/IncomingFileTransferManager.h>
#include <Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h>
#include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h>
namespace Transport {
class UserManager;
class User;
class Component;
class Buddy;
class FileTransferManager {
public:
typedef struct Transfer {
boost::shared_ptr<Swift::OutgoingFileTransfer> ft;
Swift::JID from;
Swift::JID to;
boost::shared_ptr<Swift::ReadBytestream> readByteStream;
} Transfer;
FileTransferManager(Component *component, UserManager *userManager);
virtual ~FileTransferManager();
FileTransferManager::Transfer sendFile(User *user, Buddy *buddy, boost::shared_ptr<Swift::ReadBytestream> 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;
};
}

View file

@ -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<Swift::SafeByteArray> data);
void _handleConnected(bool error);
void handleDisconnected();

View file

@ -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<unsigned char> read(size_t size) {
if (m_data.empty()) {
return std::vector<unsigned char>();
}
if (m_data.size() < size) {
m_finished = true;
return std::vector<unsigned char>(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<unsigned char>(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<Swift::VCard> 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<Swift::Connection> &, const std::string &data);
@ -158,7 +133,49 @@ class NetworkPluginServer {
Component *m_component;
std::list<User *> m_waitingUsers;
bool m_isNextLongRun;
std::map<unsigned long, boost::shared_ptr<DummyReadBytestream> > m_bytestreams;
std::map<unsigned long, FileTransferManager::Transfer> 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<std::vector<unsigned char> > read(size_t size) {
if (m_data.empty()) {
return boost::shared_ptr<std::vector<unsigned char> >(new std::vector<unsigned char>());
}
if (m_data.size() < size) {
boost::shared_ptr<std::vector<unsigned char> > ptr(new std::vector<unsigned char>(m_data.begin(), m_data.end()));
m_data.clear();
onDataNeeded(b, ftid);
return ptr;
}
boost::shared_ptr<std::vector<unsigned char> > ptr(new std::vector<unsigned char>(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<void (NetworkPluginServer::Backend *b, unsigned long ftid)> onDataNeeded;
virtual bool isFinished() const { return m_finished; }
private:
bool m_finished;
NetworkPluginServer::Backend *b;
unsigned long ftid;
std::string m_data;
bool neededData;
};
}

View file

@ -109,18 +109,14 @@ class User : public Swift::EntityCapsProvider {
return m_connected;
}
void sendFile(const Swift::JID& from, boost::shared_ptr<Swift::ReadBytestream> byteStream, const Swift::StreamInitiationFileInfo &info, unsigned long id);
boost::signal<void ()> onReadyToConnect;
boost::signal<void (Swift::Presence::ref presence)> onPresenceChanged;
boost::signal<void (const std::string &room, const std::string &nickname, const std::string &password)> onRoomJoined;
boost::signal<void (const std::string &room)> onRoomLeft;
boost::signal<void ()> onDisconnected;
boost::signal<void (const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long id)> 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;

View file

@ -25,17 +25,6 @@
#include "Swiften/Swiften.h"
#include "transport/userregistry.h"
// FT STUFF TODO: move me
#include <Swiften/Elements/StreamInitiationFileInfo.h>
#include <Swiften/FileTransfer/ConnectivityManager.h>
#include <Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h>
#include <Swiften/FileTransfer/IncomingFileTransferManager.h>
#include <Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h>
#include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h>
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;
};
}

View file

@ -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);

View file

@ -0,0 +1,91 @@
/**
* libtransport -- C++ library for easy XMPP Transports development
*
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
*
* 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<Swift::ConnectionServer> 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<Swift::ReadBytestream> 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;
}
}

View file

@ -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<Swift::SafeByteArray> 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;
}

View file

@ -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<DummyReadBytestream> bytestream(new DummyReadBytestream());
Backend *c = (Backend *) user->getData();
boost::shared_ptr<DummyReadBytestream> 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<Swift::SafeByteArray> data) {
@ -708,7 +740,7 @@ void NetworkPluginServer::handleDataRead(Backend *c, boost::shared_ptr<Swift::Sa
handleFTStartPayload(wrapper.payload());
break;
case pbnetwork::WrapperMessage_Type_TYPE_FT_DATA:
handleFTDataPayload(wrapper.payload());
handleFTDataPayload(c, wrapper.payload());
break;
default:
return;
@ -863,7 +895,6 @@ void NetworkPluginServer::handleUserCreated(User *user) {
user->onPresenceChanged.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;

View file

@ -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;

View file

@ -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<Swift::ReadBytestream> byteStream, const Swift::StreamInitiationFileInfo &info, unsigned long id) {
boost::shared_ptr<Swift::OutgoingFileTransfer> 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();
}
}
}

View file

@ -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<Swift::ConnectionServer> 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(){