soc.2009.transport: cecedf58: Straight filetransfer from XMPP to legac...
hanzz at soc.pidgin.im
hanzz at soc.pidgin.im
Mon Aug 3 12:48:25 EDT 2009
-----------------------------------------------------------------
Revision: cecedf582b6865f650e7dbd0217ef6f9c99352c1
Ancestor: 1c6ca4ca22b62be96ffd6fdf58c641abd0cfbea2
Author: hanzz at soc.pidgin.im
Date: 2009-08-03T16:42:20
Branch: im.pidgin.soc.2009.transport
URL: http://d.pidgin.im/viewmtn/revision/info/cecedf582b6865f650e7dbd0217ef6f9c99352c1
Modified files:
filetransfermanager.cpp filetransferrepeater.cpp
filetransferrepeater.h main.cpp user.cpp user.h
ChangeLog:
Straight filetransfer from XMPP to legacy network should work now
-------------- next part --------------
============================================================
--- filetransfermanager.cpp 896a81de7b5782a842f40bdcfcbd0d6201a38ad3
+++ filetransfermanager.cpp 72f34a8797160677c719816709507f51d6f46433
@@ -20,6 +20,7 @@
#include "filetransfermanager.h"
#include "usermanager.h"
+#include "filetransferrepeater.h"
void FileTransferManager::setSIProfileFT(gloox::SIProfileFT *sipft,GlooxMessageHandler *parent) {
m_sip = sipft;
@@ -32,14 +33,15 @@ void FileTransferManager::handleFTReques
m_info[sid].filename = name;
m_info[sid].size = size;
- User *user = p->userManager()->getUserByJID(from.username());
+ User *user = p->userManager()->getUserByJID(from.bare());
if (user) {
+ Log().Get(user->jid()) << "has user";
if (user->account()){
+ Log().Get(user->jid()) << "has account";
if (user->isConnected()){
Log().Get(user->jid()) << "sending file";
+ user->addFiletransfer(from, sid, SIProfileFT::FTTypeS5B, to, size);
serv_send_file(purple_account_get_connection(user->account()),to.username().c_str(), name.c_str());
- // GlooxMessageHandler::instance()->ft->acceptFT(from, sid, SIProfileFT::FTTypeS5B, to);
- user->addFiletransfer(from, sid, SIProfileFT::FTTypeS5B, to);
}
}
}
@@ -47,28 +49,39 @@ void FileTransferManager::handleFTBytest
void FileTransferManager::handleFTBytestream (Bytestream *bs) {
+ Log().Get("a") << "handleFTBytestream";
if (std::find(m_sendlist.begin(), m_sendlist.end(), bs->target().full()) == m_sendlist.end()) {
- std::string filename = m_info[bs->sid()].filename;
- // replace invalid characters
- for (std::string::iterator it = filename.begin(); it != filename.end(); ++it) {
- if (*it == '\\' || *it == '&' || *it == '/' || *it == '?' || *it == '*' || *it == ':') {
- *it = '_';
- }
- }
- filename=p->configuration().filetransferCache+"/"+bs->target().username()+"-"+p->j->getID()+"-"+filename;
+// std::string filename = m_info[bs->sid()].filename;
+// // replace invalid characters
+// for (std::string::iterator it = filename.begin(); it != filename.end(); ++it) {
+// if (*it == '\\' || *it == '&' || *it == '/' || *it == '?' || *it == '*' || *it == ':') {
+// *it = '_';
+// }
+// }
+// filename=p->configuration().filetransferCache+"/"+bs->target().username()+"-"+p->j->getID()+"-"+filename;
+//
+// mutex->lock();
+// m_progress[bs->sid()].filename=filename;
+// m_progress[bs->sid()].incoming=true;
+// m_progress[bs->sid()].state=0;
+// m_progress[bs->sid()].user=bs->initiator().bare();
+// m_progress[bs->sid()].to=bs->initiator();
+// m_progress[bs->sid()].from=bs->target();
+// m_progress[bs->sid()].stream=bs;
+// std::cout << "FROM:" << bs->initiator().full() << " TO:" << bs->target().full();
+//
+// mutex->unlock();
+// new ReceiveFile(bs,filename, m_info[bs->sid()].size,mutex,this);
+
+ User *user = p->userManager()->getUserByJID(bs->initiator().bare());
+ Log().Get("a") << "wants user" << bs->initiator().bare();
+ if (!user) return;
+ Log().Get("a") << "wants repeater" << bs->target().username();
+ FiletransferRepeater *repeater = user->removeFiletransfer(bs->target().username());
+ if (!repeater) return;
- mutex->lock();
- m_progress[bs->sid()].filename=filename;
- m_progress[bs->sid()].incoming=true;
- m_progress[bs->sid()].state=0;
- m_progress[bs->sid()].user=bs->initiator().bare();
- m_progress[bs->sid()].to=bs->initiator();
- m_progress[bs->sid()].from=bs->target();
- m_progress[bs->sid()].stream=bs;
- std::cout << "FROM:" << bs->initiator().full() << " TO:" << bs->target().full();
-
- mutex->unlock();
- new ReceiveFile(bs,filename, m_info[bs->sid()].size,mutex,this);
+ repeater->handleFTReceiveBytestream(bs);
+
} else {
// zatim to nepotrebujem u odchozich filu
// mutex->lock();
============================================================
--- filetransferrepeater.cpp afc5cb1f5ffab85652107c99717c9c3a697d341a
+++ filetransferrepeater.cpp 059ab4f8d05ee12cf866684d3075bd8082738e2f
@@ -21,8 +21,83 @@
#include "filetransferrepeater.h"
#include "main.h"
-FiletransferRepeater::FiletransferRepeater(GlooxMessageHandler *main, const JID& to, const std::string& sid, SIProfileFT::StreamType type, const JID& from) {
+
+ReceiveFileStraight::ReceiveFileStraight(gloox::Bytestream *stream, int size, FiletransferRepeater *manager) {
+ m_stream = stream;
+ m_size = size;
+ m_stream->registerBytestreamDataHandler (this);
+ m_finished = false;
+ m_parent = manager;
+ if(!m_stream->connect()) {
+ Log().Get("ReceiveFileStraight") << "connection can't be established!";
+ return;
+ }
+ run();
+}
+
+ReceiveFileStraight::~ReceiveFileStraight() {
+
+}
+
+void ReceiveFileStraight::exec() {
+ Log().Get("ReceiveFileStraight") << "starting receiveFile thread";
+// m_stream->handleConnect(m_stream->connectionImpl());
+ Log().Get("ReceiveFileStraight") << "begin receiving this file";
+ while (!m_finished) {
+ m_stream->recv();
+ }
+}
+
+void ReceiveFileStraight::handleBytestreamData(gloox::Bytestream *s5b, const std::string &data) {
+ getMutex()->lock();
+ m_parent->gotData(data);
+ getMutex()->unlock();
+}
+
+void ReceiveFileStraight::handleBytestreamError(gloox::Bytestream *s5b, const gloox::IQ &iq) {
+ Log().Get("ReceiveFileStraight") << "STREAM ERROR!";
+// Log().Get("ReceiveFileStraight") << stanza->xml();
+}
+
+void ReceiveFileStraight::handleBytestreamOpen(gloox::Bytestream *s5b) {
+ Log().Get("ReceiveFileStraight") << "stream opened...";
+}
+
+void ReceiveFileStraight::handleBytestreamClose(gloox::Bytestream *s5b) {
+ if (m_finished){
+ Log().Get("ReceiveFileStraight") << "Transfer finished and we're already finished => deleting receiveFile thread";
+ delete this;
+ }
+ else{
+ Log().Get("ReceiveFileStraight") << "Transfer finished";
+ m_finished = true;
+ }
+}
+
+
+
+
+
+static size_t ui_read_fnc(guchar *buffer, size_t size, PurpleXfer *xfer) {
+ FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
+ repeater->getResender()->getMutex()->lock();
+ if (repeater->getBuffer().empty()) {
+ repeater->wantsData();
+ buffer = (guchar*) g_strdup("");
+ repeater->getResender()->getMutex()->unlock();
+ return 0;
+ }
+ else {
+ buffer = (guchar*) g_strdup(repeater->getBuffer().c_str());
+ size_t s = repeater->getBuffer().size();
+ repeater->getResender()->getMutex()->unlock();
+ return s;
+ }
+}
+
+FiletransferRepeater::FiletransferRepeater(GlooxMessageHandler *main, const JID& to, const std::string& sid, SIProfileFT::StreamType type, const JID& from, long size) {
m_main = main;
+ m_size = size;
m_to = to;
m_sid = sid;
m_type = type;
@@ -32,6 +107,28 @@ void FiletransferRepeater::registerXfer(
void FiletransferRepeater::registerXfer(PurpleXfer *xfer) {
m_xfer = xfer;
+ purple_xfer_set_ui_read_fnc(m_xfer, ui_read_fnc);
+// purple_xfer_set_local_filename(xfer, filename);
+ purple_xfer_set_size(xfer, m_size);
+ m_xfer->ui_data = this;
}
+void FiletransferRepeater::fileSendStart() {
+ Log().Get("ReceiveFileStraight") << "fileSendStart!" << m_from.full() << " " << m_to.full();
+ m_main->ft->acceptFT(m_to, m_sid, m_type, m_from.resource().empty() ? std::string(m_from.bare() + "/bot") : m_from);
+}
+void FiletransferRepeater::handleFTReceiveBytestream(Bytestream *bs) {
+ Log().Get("ReceiveFileStraight") << "new!";
+ m_resender = new ReceiveFileStraight(bs, 0, this);
+}
+
+void FiletransferRepeater::gotData(const std::string &data) {
+ m_buffer = data;
+ if (m_wantsData) {
+ m_wantsData = false;
+ purple_xfer_ui_got_data(m_xfer);
+ }
+}
+
+
============================================================
--- filetransferrepeater.h efd6b9522c2248dd249a57d249e48b782f9e35ca
+++ filetransferrepeater.h 2df39a48bdc75f78c902598f32deec1cb297eb31
@@ -25,8 +25,11 @@
#include "gloox/tag.h"
#include "gloox/presence.h"
#include "gloox/siprofileft.h"
+#include "gloox/bytestream.h"
+#include "gloox/bytestreamdatahandler.h"
#include "conversation.h"
#include "ft.h"
+#include "thread.h"
class User;
extern Localization localization;
@@ -35,13 +38,54 @@ using namespace gloox;
using namespace gloox;
+class FiletransferRepeater;
+
+class AbstractResendClass {
+ public:
+ AbstractResendClass() { m_mutex = new MyMutex(); }
+ ~AbstractResendClass() { delete m_mutex; }
+
+ MyMutex *getMutex() { return m_mutex; }
+
+ private:
+ MyMutex *m_mutex;
+};
+
+class ReceiveFileStraight : public AbstractResendClass, public BytestreamDataHandler, public Thread {
+ public:
+ ReceiveFileStraight(Bytestream *stream, int size, FiletransferRepeater *manager);
+ ~ReceiveFileStraight();
+
+ void exec();
+ void handleBytestreamData(Bytestream *s5b, const std::string &data);
+ void handleBytestreamError(Bytestream *s5b, const IQ &iq);
+ void handleBytestreamOpen(Bytestream *s5b);
+ void handleBytestreamClose(Bytestream *s5b);
+
+ void gotData(const std::string &data);
+
+ private:
+ Bytestream *m_stream;
+ std::string m_filename;
+ int m_size;
+ bool m_finished;
+ FiletransferRepeater *m_parent;
+};
+
class FiletransferRepeater {
public:
- FiletransferRepeater(GlooxMessageHandler *main, const JID& to, const std::string& sid, SIProfileFT::StreamType type, const JID& from);
+ FiletransferRepeater(GlooxMessageHandler *main, const JID& to, const std::string& sid, SIProfileFT::StreamType type, const JID& from, long size);
~FiletransferRepeater() {}
void registerXfer(PurpleXfer *xfer);
+ void fileSendStart();
+ void handleFTReceiveBytestream(Bytestream *bs);
+ void gotData(const std::string &data);
+
+ std::string & getBuffer() { return m_buffer; }
+ AbstractResendClass *getResender() { return m_resender; }
+ void wantsData() { m_wantsData = true; }
private:
GlooxMessageHandler *m_main;
@@ -49,7 +93,12 @@ class FiletransferRepeater {
std::string m_sid;
SIProfileFT::StreamType m_type;
JID m_from;
+ long m_size;
PurpleXfer *m_xfer;
+
+ std::string m_buffer;
+ AbstractResendClass *m_resender;
+ bool m_wantsData;
};
============================================================
--- main.cpp ee4ace89731f72fdf6531146fbace07adfd8c42f
+++ main.cpp 225d98b60346f83245b9ce9775ab93ee623c8024
@@ -383,28 +383,24 @@ static void * notifyMessage(PurpleNotify
return NULL;
}
-static size_t ui_read_fnc(guchar *buffer, size_t size, PurpleXfer *xfer) {
- return size;
-}
-
static void XferCreated(PurpleXfer *xfer) {
std::string remote_user(purple_xfer_get_remote_user(xfer));
User *user = GlooxMessageHandler::instance()->userManager()->getUserByAccount(purple_xfer_get_account(xfer));
if (!user) return;
- FiletransferRepeater *repeater = user->removeFiletransfer(remote_user);
+ FiletransferRepeater *repeater = user->getFiletransfer(remote_user);
+ Log().Get(user->jid()) << "get filetransferRepeater" << remote_user;
if (!repeater) return;
-
+ Log().Get(user->jid()) << "registerXfer";
repeater->registerXfer(xfer);
-
-// purple_xfer_set_ui_read_fnc(xfer, ui_read_fnc);
-
-// xfer->ui_data = new
+
}
static void fileSendStart(PurpleXfer *xfer) {
-// GlooxMessageHandler::instance()->ft->acceptFT(from, sid, SIProfileFT::FTTypeS5B, to);
+ FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
+ repeater->fileSendStart();
+ Log().Get("filesend") << "fileSendStart()";
}
@@ -624,7 +620,7 @@ GlooxMessageHandler::GlooxMessageHandler
Log().Get("gloox") << "connecting to: " << m_configuration.server << " as " << m_configuration.jid << " with password " << m_configuration.password;
j = new HiComponent("jabber:component:accept",m_configuration.server,m_configuration.jid,m_configuration.password,m_configuration.port);
-// j->logInstance().registerLogHandler( LogLevelDebug, LogAreaAll, this );
+ j->logInstance().registerLogHandler( LogLevelDebug, LogAreaAll, this );
GMainLoop *loop = g_main_loop_new(NULL, FALSE);
signal(SIGCHLD, SIG_IGN);
============================================================
--- user.cpp ead4ec48a2097693d94d865ca624cb569b6bc462
+++ user.cpp d44b97b2ab46e4fd1989802f91b8bcb793bc45c6
@@ -428,7 +428,7 @@ void User::purpleBuddyChanged(PurpleBudd
* Called when something related to this buddy changed...
*/
void User::purpleBuddyChanged(PurpleBuddy *buddy){
- if (buddy==NULL || m_connected == false)
+ if (buddy==NULL /*|| m_connected == false*/)
return;
std::string alias;
if (purple_buddy_get_server_alias(buddy))
@@ -1249,9 +1249,10 @@ void User::receivedPresence(const Presen
delete stanzaTag;
}
-void User::addFiletransfer( const JID& to, const std::string& sid, SIProfileFT::StreamType type, const JID& from ) {
- FiletransferRepeater *ft = new FiletransferRepeater(p, to, sid, type, from);
+void User::addFiletransfer( const JID& to, const std::string& sid, SIProfileFT::StreamType type, const JID& from, long size ) {
+ FiletransferRepeater *ft = new FiletransferRepeater(p, to, sid, type, from, size);
g_hash_table_replace(m_filetransfers, g_strdup(to.bare() == m_jid ? from.username().c_str() : to.username().c_str()), ft);
+ Log().Get("filetransfer") << "adding FT Class as jid:" << std::string(to.bare() == m_jid ? from.username() : to.username());
}
User::~User(){
============================================================
--- user.h c34ca15761e1a38e0802bb6c5f77ccb6009734f5
+++ user.h e4868de2cc738020837962982598d66e9e62563a
@@ -120,9 +120,9 @@ class User {
void disconnected();
// Filetransfers
- void addFiletransfer( const JID& to, const std::string& sid, SIProfileFT::StreamType type, const JID& from );
- FiletransferRepeater* removeFiletransfer(std::string &from) { FiletransferRepeater *repeater = (FiletransferRepeater *) g_hash_table_lookup(m_filetransfers, from.c_str()); if (repeater) g_hash_table_remove(m_filetransfers, from.c_str()); return repeater; }
-
+ void addFiletransfer( const JID& to, const std::string& sid, SIProfileFT::StreamType type, const JID& from, long size );
+ FiletransferRepeater* removeFiletransfer(std::string from) { FiletransferRepeater *repeater = (FiletransferRepeater *) g_hash_table_lookup(m_filetransfers, from.c_str()); if (repeater) g_hash_table_remove(m_filetransfers, from.c_str()); return repeater; }
+ FiletransferRepeater* getFiletransfer(std::string from) { FiletransferRepeater *repeater = (FiletransferRepeater *) g_hash_table_lookup(m_filetransfers, from.c_str()); return repeater; }
std::string actionData;
// Connected
More information about the Commits
mailing list