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