diff options
| author | Remko Tronçon <git@el-tramo.be> | 2011-03-26 10:09:46 (GMT) | 
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2011-04-18 19:11:40 (GMT) | 
| commit | bb37c9f89e4135f3128fc98c23ea19eea945c4cd (patch) | |
| tree | 92e9504a27d6eaa8182bb0bab8a7556825a46ad7 | |
| parent | 039636edc1b151431cba21a28986ff2be66b5349 (diff) | |
| download | swift-bb37c9f89e4135f3128fc98c23ea19eea945c4cd.zip swift-bb37c9f89e4135f3128fc98c23ea19eea945c4cd.tar.bz2 | |
Jingle refactoring.
64 files changed, 1211 insertions, 337 deletions
| diff --git a/Swiften/Base/ByteArray.cpp b/Swiften/Base/ByteArray.cpp index 928e145..c3869fc 100644 --- a/Swiften/Base/ByteArray.cpp +++ b/Swiften/Base/ByteArray.cpp @@ -9,6 +9,10 @@  #include <fstream>  std::ostream& operator<<(std::ostream& os, const Swift::ByteArray& s) { +	return operator<<(os, s.getDataVector()); +} + +std::ostream& operator<<(std::ostream& os, const std::vector<unsigned char>& s) {  	std::ios::fmtflags oldFlags = os.flags();   	os << std::hex;  	for (Swift::ByteArray::const_iterator i = s.begin(); i != s.end(); ++i) { @@ -37,4 +41,35 @@ void ByteArray::readFromFile(const std::string& file) {  	input.close();  } +std::vector<unsigned char> ByteArray::create(const std::string& s) { +	return std::vector<unsigned char>(s.begin(), s.end()); +} + +std::vector<unsigned char> ByteArray::create(const char* c) { +	std::vector<unsigned char> data; +	while (*c) { +		data.push_back(static_cast<unsigned char>(*c)); +		++c; +	} +	return data; +} + +std::vector<unsigned char> ByteArray::create(const char* c, size_t n) { +	std::vector<unsigned char> data; +	if (n > 0) { +		data.resize(n); +		memcpy(&data[0], c, n); +	} +	return data; +} + +std::vector<unsigned char> ByteArray::create(const unsigned char* c, size_t n) { +	std::vector<unsigned char> data; +	if (n > 0) { +		data.resize(n); +		memcpy(&data[0], c, n); +	} +	return data; +} +  } diff --git a/Swiften/Base/ByteArray.h b/Swiften/Base/ByteArray.h index 2059052..9e7a928 100644 --- a/Swiften/Base/ByteArray.h +++ b/Swiften/Base/ByteArray.h @@ -130,9 +130,19 @@ namespace Swift {  				data_.clear();  			} +			const std::vector<unsigned char>& getDataVector() const { +				return data_; +			} + +			static std::vector<unsigned char> create(const std::string& s); +			static std::vector<unsigned char> create(const char* c); +			static std::vector<unsigned char> create(const unsigned char* c, size_t n); +			static std::vector<unsigned char> create(const char* c, size_t n); +  		private:  			std::vector<unsigned char> data_;  	};  }  std::ostream& operator<<(std::ostream& os, const Swift::ByteArray& s); +std::ostream& operator<<(std::ostream& os, const std::vector<unsigned char>& s); diff --git a/Swiften/Client/DummyStanzaChannel.h b/Swiften/Client/DummyStanzaChannel.h index b9f05c3..306e2b4 100644 --- a/Swiften/Client/DummyStanzaChannel.h +++ b/Swiften/Client/DummyStanzaChannel.h @@ -56,6 +56,22 @@ namespace Swift {  				return iqStanza && iqStanza->getType() == type && iqStanza->getTo() == jid && iqStanza->getPayload<T>();  			} +			bool isResultAtIndex(size_t index, const std::string& id) { +				if (index >= sentStanzas.size()) { +					return false; +				} +				boost::shared_ptr<IQ> iqStanza = boost::dynamic_pointer_cast<IQ>(sentStanzas[index]); +				return iqStanza && iqStanza->getType() == IQ::Result && iqStanza->getID() == id; +			} + +			bool isErrorAtIndex(size_t index, const std::string& id) { +				if (index >= sentStanzas.size()) { +					return false; +				} +				boost::shared_ptr<IQ> iqStanza = boost::dynamic_pointer_cast<IQ>(sentStanzas[index]); +				return iqStanza && iqStanza->getType() == IQ::Error && iqStanza->getID() == id; +			} +  			template<typename T> boost::shared_ptr<T> getStanzaAtIndex(size_t index) {  				if (sentStanzas.size() <= index) {  					return boost::shared_ptr<T>(); diff --git a/Swiften/Elements/IBB.h b/Swiften/Elements/IBB.h index faee71d..8138e83 100644 --- a/Swiften/Elements/IBB.h +++ b/Swiften/Elements/IBB.h @@ -6,11 +6,11 @@  #pragma once -#include <boost/shared_ptr.hpp>  #include <string> +#include <vector> +#include <boost/shared_ptr.hpp> -#include "Swiften/Base/ByteArray.h" -#include "Swiften/Elements/Payload.h" +#include <Swiften/Elements/Payload.h>  namespace Swift {  	class IBB : public Payload { @@ -36,7 +36,7 @@ namespace Swift {  				return result;  			} -			static IBB::ref createIBBData(const std::string& streamID, int sequenceNumber, const ByteArray& data) { +			static IBB::ref createIBBData(const std::string& streamID, int sequenceNumber, const std::vector<unsigned char>& data) {  				IBB::ref result(new IBB(Data, streamID));  				result->setSequenceNumber(sequenceNumber);  				result->setData(data); @@ -71,11 +71,11 @@ namespace Swift {  				return streamID;  			} -			const ByteArray& getData() const { +			const std::vector<unsigned char>& getData() const {  				return data;  			} -			void setData(const ByteArray& data) { +			void setData(const std::vector<unsigned char>& data) {  				this->data = data;  			} @@ -98,7 +98,7 @@ namespace Swift {  		private:  			Action action;  			std::string streamID; -			ByteArray data; +			std::vector<unsigned char> data;  			StanzaType stanzaType;  			int blockSize;  			int sequenceNumber; diff --git a/Swiften/Elements/JingleContent.h b/Swiften/Elements/JingleContentPayload.h index 97b071f..c44a806 100644 --- a/Swiften/Elements/JingleContent.h +++ b/Swiften/Elements/JingleContentPayload.h @@ -13,12 +13,12 @@  #include <Swiften/JID/JID.h>  #include <Swiften/Elements/Payload.h>  #include <Swiften/Elements/JingleDescription.h> -#include <Swiften/Elements/JingleTransport.h> +#include <Swiften/Elements/JingleTransportPayload.h>  namespace Swift { -	class JingleContent : public Payload { +	class JingleContentPayload : public Payload {  		public: -			typedef boost::shared_ptr<JingleContent> ref; +			typedef boost::shared_ptr<JingleContentPayload> ref;  			enum Creator {  				InitiatorCreator, @@ -32,10 +32,18 @@ namespace Swift {  				BothSenders,  			};*/ +			Creator getCreator() const { +				return creator; +			} +  			void setCreator(Creator creator) {  				this->creator = creator;  			} +			const std::string& getName() const { +				return name; +			} +  			void setName(const std::string& name) {  				this->name = name;  			} @@ -83,10 +91,6 @@ namespace Swift {  			std::string name;  			//Senders senders;  			std::vector<JingleDescription::ref> descriptions; -<<<<<<< HEAD:Swiften/Elements/JingleContent.h -			std::vector<JingleTransport::ref> transports; -=======  			std::vector<boost::shared_ptr<JingleTransportPayload> > transports; ->>>>>>> 7c05f3f... Cleaned up headers.:Swiften/Elements/JingleContentPayload.h  	};  } diff --git a/Swiften/Elements/JingleIBBTransport.h b/Swiften/Elements/JingleIBBTransportPayload.h index faa5af3..67aab09 100644 --- a/Swiften/Elements/JingleIBBTransport.h +++ b/Swiften/Elements/JingleIBBTransportPayload.h @@ -6,12 +6,16 @@  #pragma once +#include <boost/shared_ptr.hpp>  #include <string> -#include <Swiften/Elements/JingleTransport.h> + +#include <Swiften/Elements/JingleTransportPayload.h>  namespace Swift { -	class JingleIBBTransport : public JingleTransport { +	class JingleIBBTransportPayload : public JingleTransportPayload {  		public: +			typedef boost::shared_ptr<JingleIBBTransportPayload> ref; +  			enum StanzaType {  				IQStanza,  				MessageStanza, diff --git a/Swiften/Elements/JinglePayload.h b/Swiften/Elements/JinglePayload.h index 59d3c99..be02543 100644 --- a/Swiften/Elements/JinglePayload.h +++ b/Swiften/Elements/JinglePayload.h @@ -12,7 +12,7 @@  #include <string>  #include <Swiften/JID/JID.h>  #include <Swiften/Elements/Payload.h> -#include <Swiften/Elements/JingleContent.h> +#include <Swiften/Elements/JingleContentPayload.h>  namespace Swift { @@ -98,11 +98,11 @@ namespace Swift {  				return sessionID;  			} -			void addContent(JingleContent::ref content) { +			void addContent(JingleContentPayload::ref content) {  				this->contents.push_back(content);  			} -			const std::vector<JingleContent::ref> getContents() const { +			const std::vector<JingleContentPayload::ref> getContents() const {  				return contents;  			} @@ -119,7 +119,7 @@ namespace Swift {  			JID initiator;  			JID responder;  			std::string sessionID; -			std::vector<JingleContent::ref> contents; +			std::vector<JingleContentPayload::ref> contents;  			boost::optional<Reason> reason;  	};  } diff --git a/Swiften/Elements/JingleS5BTransport.h b/Swiften/Elements/JingleS5BTransportPayload.h index 4522417..7b3089f 100644 --- a/Swiften/Elements/JingleS5BTransport.h +++ b/Swiften/Elements/JingleS5BTransportPayload.h @@ -6,11 +6,13 @@  #pragma once -#include <Swiften/Elements/JingleTransport.h> +#include <Swiften/Elements/JingleTransportPayload.h>  #include <Swiften/Elements/Bytestreams.h> +// FIXME: Remove Bytestreams, and replace by our own candidate +  namespace Swift { -	class JingleS5BTransport : public JingleTransport { +	class JingleS5BTransportPayload : public JingleTransportPayload {  		public:  			const Bytestreams& getInfo() const {  				return info; diff --git a/Swiften/Elements/JingleTransport.h b/Swiften/Elements/JingleTransportPayload.h index 7a9ea29..7a9ea29 100644 --- a/Swiften/Elements/JingleTransport.h +++ b/Swiften/Elements/JingleTransportPayload.h diff --git a/Swiften/Examples/SendFile/SendFile.cpp b/Swiften/Examples/SendFile/SendFile.cpp index 565c51f..d8300be 100644 --- a/Swiften/Examples/SendFile/SendFile.cpp +++ b/Swiften/Examples/SendFile/SendFile.cpp @@ -16,7 +16,7 @@  #include "Swiften/EventLoop/EventLoop.h"  #include "Swiften/Client/ClientXMLTracer.h"  #include "Swiften/EventLoop/SimpleEventLoop.h" -#include "Swiften/FileTransfer/OutgoingFileTransfer.h" +#include "Swiften/FileTransfer/OutgoingSIFileTransfer.h"  #include "Swiften/FileTransfer/FileReadBytestream.h"  #include "Swiften/FileTransfer/SOCKS5BytestreamServer.h"  #include "Swiften/Network/BoostConnectionServer.h" @@ -66,7 +66,7 @@ class FileSender {  	private:  		void handleConnected() {  			client->sendPresence(Presence::create()); -			transfer = new OutgoingFileTransfer("myid",	client->getJID(), recipient, file.filename(), boost::filesystem::file_size(file), "A file", boost::shared_ptr<FileReadBytestream>(new FileReadBytestream(file)), client->getIQRouter(), socksBytestreamServer); +			transfer = new OutgoingSIFileTransfer("myid",	client->getJID(), recipient, file.filename(), boost::filesystem::file_size(file), "A file", boost::shared_ptr<FileReadBytestream>(new FileReadBytestream(file)), client->getIQRouter(), socksBytestreamServer);  			transfer->onFinished.connect(boost::bind(&FileSender::handleFileTransferFinished, this, _1));  			transfer->start();  		} @@ -101,7 +101,7 @@ class FileSender {  		boost::filesystem::path file;  		Client* client;  		ClientXMLTracer* tracer; -		OutgoingFileTransfer* transfer; +		OutgoingSIFileTransfer* transfer;  }; diff --git a/Swiften/FileTransfer/ByteArrayReadBytestream.h b/Swiften/FileTransfer/ByteArrayReadBytestream.h index d459658..4704db6 100644 --- a/Swiften/FileTransfer/ByteArrayReadBytestream.h +++ b/Swiften/FileTransfer/ByteArrayReadBytestream.h @@ -6,31 +6,32 @@  #pragma once -#include "Swiften/FileTransfer/ReadBytestream.h" -#include "Swiften/Base/ByteArray.h" +#include <vector> + +#include <Swiften/FileTransfer/ReadBytestream.h>  namespace Swift {  	class ByteArrayReadBytestream : public ReadBytestream {  		public: -			ByteArrayReadBytestream(const ByteArray& data) : data(data), position(0) { +			ByteArrayReadBytestream(const std::vector<unsigned char>& data) : data(data), position(0) {  			} -			virtual ByteArray read(size_t size) { +			virtual std::vector<unsigned char> read(size_t size) {  				size_t readSize = size; -				if (position + readSize > data.getSize()) { -					readSize = data.getSize() - position; +				if (position + readSize > data.size()) { +					readSize = data.size() - position;  				} -				ByteArray result(data.getData() + position, readSize); +				std::vector<unsigned char> result(data.begin() + position, data.begin() + position + readSize);  				position += readSize;  				return result;  			}  			virtual bool isFinished() const { -				return position >= data.getSize(); +				return position >= data.size();  			}  		private: -			ByteArray data; +			std::vector<unsigned char> data;  			size_t position;  	};  } diff --git a/Swiften/FileTransfer/ByteArrayWriteBytestream.h b/Swiften/FileTransfer/ByteArrayWriteBytestream.h new file mode 100644 index 0000000..6c360e6 --- /dev/null +++ b/Swiften/FileTransfer/ByteArrayWriteBytestream.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/FileTransfer/WriteBytestream.h> + +namespace Swift { +	class ByteArrayWriteBytestream : public WriteBytestream { +		public: +			ByteArrayWriteBytestream() { +			} + +			virtual void write(const std::vector<unsigned char>& bytes) { +				data.insert(data.end(), bytes.begin(), bytes.end()); +			} + +			const std::vector<unsigned char>& getData() const { +				return data; +			} + +		private: +			std::vector<unsigned char> data; +	}; +} diff --git a/Swiften/FileTransfer/FileReadBytestream.cpp b/Swiften/FileTransfer/FileReadBytestream.cpp index c08747b..e997366 100644 --- a/Swiften/FileTransfer/FileReadBytestream.cpp +++ b/Swiften/FileTransfer/FileReadBytestream.cpp @@ -21,14 +21,14 @@ FileReadBytestream::~FileReadBytestream() {  	}  } -ByteArray FileReadBytestream::read(size_t size)  { +std::vector<unsigned char> FileReadBytestream::read(size_t size)  {  	if (!stream) {  		stream = new boost::filesystem::ifstream(file, std::ios_base::in|std::ios_base::binary);  	} -	ByteArray result; +	std::vector<unsigned char> result;  	result.resize(size);  	assert(stream->good()); -	stream->read(reinterpret_cast<char*>(result.getData()), size); +	stream->read(reinterpret_cast<char*>(&result[0]), size);  	result.resize(stream->gcount());  	return result;  } diff --git a/Swiften/FileTransfer/FileReadBytestream.h b/Swiften/FileTransfer/FileReadBytestream.h index 4027c43..f136a68 100644 --- a/Swiften/FileTransfer/FileReadBytestream.h +++ b/Swiften/FileTransfer/FileReadBytestream.h @@ -17,7 +17,7 @@ namespace Swift {  			FileReadBytestream(const boost::filesystem::path& file);  			~FileReadBytestream(); -			virtual ByteArray read(size_t size) ; +			virtual std::vector<unsigned char> read(size_t size);  			virtual bool isFinished() const;  		private: diff --git a/Swiften/FileTransfer/FileWriteBytestream.cpp b/Swiften/FileTransfer/FileWriteBytestream.cpp index 4d29bd1..803a10b 100644 --- a/Swiften/FileTransfer/FileWriteBytestream.cpp +++ b/Swiften/FileTransfer/FileWriteBytestream.cpp @@ -21,12 +21,12 @@ FileWriteBytestream::~FileWriteBytestream() {  	}  } -void FileWriteBytestream::write(const ByteArray& data) { +void FileWriteBytestream::write(const std::vector<unsigned char>& data) {  	if (!stream) {  		stream = new boost::filesystem::ofstream(file, std::ios_base::out|std::ios_base::binary);  	}  	assert(stream->good()); -	stream->write(reinterpret_cast<const char*>(data.getData()), data.getSize()); +	stream->write(reinterpret_cast<const char*>(&data[0]), data.size());  }  } diff --git a/Swiften/FileTransfer/FileWriteBytestream.h b/Swiften/FileTransfer/FileWriteBytestream.h index 16f4b1f..8cfa718 100644 --- a/Swiften/FileTransfer/FileWriteBytestream.h +++ b/Swiften/FileTransfer/FileWriteBytestream.h @@ -9,7 +9,7 @@  #include <boost/filesystem/path.hpp>  #include <boost/filesystem/fstream.hpp> -#include "Swiften/FileTransfer/WriteBytestream.h" +#include <Swiften/FileTransfer/WriteBytestream.h>  namespace Swift {  	class FileWriteBytestream : public WriteBytestream { @@ -17,7 +17,7 @@ namespace Swift {  			FileWriteBytestream(const boost::filesystem::path& file);  			~FileWriteBytestream(); -			virtual void write(const ByteArray&); +			virtual void write(const std::vector<unsigned char>&);  		private:  			boost::filesystem::path file; diff --git a/Swiften/FileTransfer/IBBReceiveSession.cpp b/Swiften/FileTransfer/IBBReceiveSession.cpp index f980c47..566dcca 100644 --- a/Swiften/FileTransfer/IBBReceiveSession.cpp +++ b/Swiften/FileTransfer/IBBReceiveSession.cpp @@ -4,32 +4,96 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/FileTransfer/IBBReceiveSession.h" +#include <Swiften/FileTransfer/IBBReceiveSession.h>  #include <boost/bind.hpp> -#include <iostream> -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/FileTransfer/IBBRequest.h" -#include "Swiften/FileTransfer/BytestreamException.h" +#include <Swiften/Base/Log.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/FileTransfer/IBBRequest.h> +#include <Swiften/FileTransfer/BytestreamException.h> +#include <Swiften/Queries/SetResponder.h>  namespace Swift { -IBBReceiveSession::IBBReceiveSession(const std::string& id, const JID& from, size_t size, WriteBytestream::ref bytestream, IQRouter* router) : SetResponder<IBB>(router), id(id), from(from), size(size), bytestream(bytestream), router(router), sequenceNumber(0), active(false), receivedSize(0) { +class IBBReceiveSession::IBBResponder : public SetResponder<IBB> { +	public: +		IBBResponder(IBBReceiveSession* session, IQRouter* router) : SetResponder<IBB>(router), session(session), sequenceNumber(0), receivedSize(0) { +		} + +		virtual bool handleSetRequest(const JID& from, const JID&, const std::string& id, IBB::ref ibb) { +			if (from == session->from && ibb->getStreamID() == session->id) { +				if (ibb->getAction() == IBB::Data) { +					if (sequenceNumber == ibb->getSequenceNumber()) { +						session->onDataReceived(ibb->getData()); +						receivedSize += ibb->getData().size(); +						sequenceNumber++; +						sendResponse(from, id, IBB::ref()); +						if (receivedSize >= session->size) { +							if (receivedSize > session->size) { +								std::cerr << "Warning: Received more data than expected" << std::endl; +							} +							session->finish(boost::optional<FileTransferError>()); +						} +					} +					else { +						SWIFT_LOG(warning) << "Received data out of order" << std::endl; +						sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Cancel); +						session->finish(FileTransferError(FileTransferError::ClosedError)); +					} +				} +				else if (ibb->getAction() == IBB::Open) { +					sendResponse(from, id, IBB::ref()); +				} +				else if (ibb->getAction() == IBB::Close) { +					sendResponse(from, id, IBB::ref()); +					session->finish(FileTransferError(FileTransferError::ClosedError)); +				} +				return true; +			} +			return false; +		} + +	private: +		IBBReceiveSession* session; +		int sequenceNumber; +		size_t receivedSize; +}; + + +IBBReceiveSession::IBBReceiveSession( +		const std::string& id,  +		const JID& from,  +		size_t size,  +		IQRouter* router) :  +			id(id),  +			from(from),  +			size(size),  +			router(router),  +			active(false) { +	responder = new IBBResponder(this, router);  }  IBBReceiveSession::~IBBReceiveSession() { +	if (active) { +		SWIFT_LOG(warning) << "Session still active" << std::endl; +	} +	delete responder;  }  void IBBReceiveSession::start() {  	active = true; +	responder->start();  }  void IBBReceiveSession::stop() { -	if (active && router->isAvailable()) { -		IBBRequest::create(from, IBB::createIBBClose(id), router)->send(); +	responder->stop(); +	if (active) { +		if (router->isAvailable()) { +			IBBRequest::create(from, IBB::createIBBClose(id), router)->send(); +		} +		finish(boost::optional<FileTransferError>());  	} -	finish(boost::optional<FileTransferError>());  }  void IBBReceiveSession::finish(boost::optional<FileTransferError> error) { @@ -37,34 +101,4 @@ void IBBReceiveSession::finish(boost::optional<FileTransferError> error) {  	onFinished(error);  } -bool IBBReceiveSession::handleSetRequest(const JID& from, const JID&, const std::string& id, IBB::ref ibb) { -	if (from == this->from && ibb->getStreamID() == id) { -		if (ibb->getAction() == IBB::Data) { -			if (sequenceNumber == ibb->getSequenceNumber()) { -				bytestream->write(ibb->getData()); -				receivedSize += ibb->getData().getSize(); -				if (receivedSize >= size) { -					if (receivedSize > size) { -						std::cerr << "Warning: Received more data than expected" << std::endl; -					} -					finish(boost::optional<FileTransferError>()); -				} -			} -			else { -				sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Cancel); -				finish(FileTransferError(FileTransferError::ClosedError)); -			} -		} -		else if (ibb->getAction() == IBB::Open) { -			sendResponse(from, id, IBB::ref()); -		} -		else if (ibb->getAction() == IBB::Close) { -			sendResponse(from, id, IBB::ref()); -			finish(FileTransferError(FileTransferError::ClosedError)); -		} -		return true; -	} -	return false; -} -  } diff --git a/Swiften/FileTransfer/IBBReceiveSession.h b/Swiften/FileTransfer/IBBReceiveSession.h index 6d936de..d512025 100644 --- a/Swiften/FileTransfer/IBBReceiveSession.h +++ b/Swiften/FileTransfer/IBBReceiveSession.h @@ -7,27 +7,30 @@  #pragma once  #include <boost/shared_ptr.hpp> -#include <boost/optional.hpp> +#include <boost/optional/optional_fwd.hpp>  #include "Swiften/Base/boost_bsignals.h"  #include "Swiften/FileTransfer/WriteBytestream.h"  #include "Swiften/JID/JID.h"  #include "Swiften/Elements/IBB.h" -#include "Swiften/Elements/ErrorPayload.h"  #include "Swiften/FileTransfer/FileTransferError.h" -#include "Swiften/Queries/SetResponder.h"  namespace Swift {  	class IQRouter; -	class IBBReceiveSession : public SetResponder<IBB> { +	class IBBReceiveSession {  		public: -			IBBReceiveSession(const std::string& id, const JID& from, size_t size, WriteBytestream::ref bytestream, IQRouter* router); +			IBBReceiveSession( +					const std::string& id,  +					const JID& from,  +					size_t size,  +					IQRouter* router);  			~IBBReceiveSession();  			void start();  			void stop(); +			boost::signal<void (const std::vector<unsigned char>&)> onDataReceived;  			boost::signal<void (boost::optional<FileTransferError>)> onFinished;  		private: @@ -35,13 +38,14 @@ namespace Swift {  			void finish(boost::optional<FileTransferError>);  		private: +			class IBBResponder; +			friend class IBBResponder; +  			std::string id;  			JID from;  			size_t size; -			WriteBytestream::ref bytestream;  			IQRouter* router; -			int sequenceNumber; +			IBBResponder* responder;  			bool active; -			size_t receivedSize;  	};  } diff --git a/Swiften/FileTransfer/IBBSendSession.cpp b/Swiften/FileTransfer/IBBSendSession.cpp index 52949c4..c31fe4a 100644 --- a/Swiften/FileTransfer/IBBSendSession.cpp +++ b/Swiften/FileTransfer/IBBSendSession.cpp @@ -38,7 +38,7 @@ void IBBSendSession::handleIBBResponse(IBB::ref, ErrorPayload::ref error) {  	if (!error) {  		if (!bytestream->isFinished()) {  			try { -				ByteArray data = bytestream->read(blockSize); +				std::vector<unsigned char> data = bytestream->read(blockSize);  				IBBRequest::ref request = IBBRequest::create(to, IBB::createIBBData(id, sequenceNumber, data), router);  				sequenceNumber++;  				request->onResponse.connect(boost::bind(&IBBSendSession::handleIBBResponse, this, _1, _2)); diff --git a/Swiften/FileTransfer/IncomingFileTransfer.cpp b/Swiften/FileTransfer/IncomingFileTransfer.cpp index 238ccce..7c97e4d 100644 --- a/Swiften/FileTransfer/IncomingFileTransfer.cpp +++ b/Swiften/FileTransfer/IncomingFileTransfer.cpp @@ -4,20 +4,11 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/FileTransfer/IncomingFileTransfer.h" +#include <Swiften/FileTransfer/IncomingFileTransfer.h>  namespace Swift {  IncomingFileTransfer::~IncomingFileTransfer() { - -} - -/*void IncomingFileTransfer::accept(WriteBytestream::ref) { -  } -void IncomingFileTransfer::stop() { - -}*/ -  } diff --git a/Swiften/FileTransfer/IncomingFileTransferManager.cpp b/Swiften/FileTransfer/IncomingFileTransferManager.cpp index 5535840..79d2391 100644 --- a/Swiften/FileTransfer/IncomingFileTransferManager.cpp +++ b/Swiften/FileTransfer/IncomingFileTransferManager.cpp @@ -10,8 +10,10 @@  #include <Swiften/Elements/JingleDescription.h>  #include <Swiften/Elements/JingleFileTransferDescription.h> -#include <Swiften/Elements/JingleIBBTransport.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h>  #include <Swiften/Jingle/JingleSessionManager.h> +#include <Swiften/Jingle/Jingle.h>  #include <Swiften/FileTransfer/IncomingJingleFileTransfer.h>  namespace Swift { @@ -24,12 +26,12 @@ IncomingFileTransferManager::~IncomingFileTransferManager() {  	jingleSessionManager->removeIncomingSessionHandler(this);  } -bool IncomingFileTransferManager::handleIncomingJingleSession(IncomingJingleSession::ref session) { -	JingleContent::ref content = session->getContentWithDescription<JingleFileTransferDescription>(); -	if (content) { -		// Check for supported transports -		if (content->getTransport<JingleIBBTransport>()) { -			IncomingJingleFileTransfer::ref transfer = boost::make_shared<IncomingJingleFileTransfer>(session); +bool IncomingFileTransferManager::handleIncomingJingleSession(JingleSession::ref session, const std::vector<JingleContentPayload::ref>& contents) { +	if (JingleContentPayload::ref content = Jingle::getContentWithDescription<JingleFileTransferDescription>(contents)) { +		if (content->getTransport<JingleIBBTransportPayload>() || content->getTransport<JingleS5BTransportPayload>()) { +			RemoteJingleTransportCandidateSelectorFactory* a; +			LocalJingleTransportCandidateGeneratorFactory* b; +			IncomingJingleFileTransfer::ref transfer = boost::make_shared<IncomingJingleFileTransfer>(session, content, a, b, router);  			onIncomingFileTransfer(transfer);  		}  		else { diff --git a/Swiften/FileTransfer/IncomingFileTransferManager.h b/Swiften/FileTransfer/IncomingFileTransferManager.h index a54b5cd..428a838 100644 --- a/Swiften/FileTransfer/IncomingFileTransferManager.h +++ b/Swiften/FileTransfer/IncomingFileTransferManager.h @@ -15,6 +15,8 @@  namespace Swift {  	class IQRouter;  	class JingleSessionManager; +	class RemoteJingleTransportCandidateSelectorFactory; +	class LocalJingleTransportCandidateGeneratorFactory;  	class IncomingFileTransferManager : public IncomingJingleSessionHandler {  		public: @@ -24,7 +26,7 @@ namespace Swift {  			boost::signal<void (IncomingFileTransfer::ref)> onIncomingFileTransfer;  		private: -			bool handleIncomingJingleSession(IncomingJingleSession::ref session); +			bool handleIncomingJingleSession(JingleSession::ref session, const std::vector<JingleContentPayload::ref>& contents);  		private:  			JingleSessionManager* jingleSessionManager; diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp index cb2f65c..904b53e 100644 --- a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp @@ -6,14 +6,164 @@  #include <Swiften/FileTransfer/IncomingJingleFileTransfer.h> +#include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h> +#include <Swiften/FileTransfer/JingleIncomingIBBTransport.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h> +#include <Swiften/Elements/JingleS5BTransportPayload.h> +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h> +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h> +  namespace Swift { -IncomingJingleFileTransfer::IncomingJingleFileTransfer(IncomingJingleSession::ref session) : session(session) { +IncomingJingleFileTransfer::IncomingJingleFileTransfer( +		JingleSession::ref session, +		JingleContentPayload::ref content, +		RemoteJingleTransportCandidateSelectorFactory* candidateSelectorFactory, +		LocalJingleTransportCandidateGeneratorFactory* candidateGeneratorFactory, +		IQRouter* router) : +			session(session), +			router(router), +			initialContent(content), +			contentID(content->getName(), content->getCreator()), +			state(Initial), +			remoteTransportCandidateSelectFinished(false), +			localTransportCandidateSelectFinished(false) { +	 +	candidateSelector = candidateSelectorFactory->createCandidateSelector(); +	candidateSelector->onRemoteTransportCandidateSelectFinished.connect(boost::bind(&IncomingJingleFileTransfer::handleRemoteTransportCandidateSelectFinished, this, _1)); + +	candidateGenerator = candidateGeneratorFactory->createCandidateGenerator(); +	candidateGenerator->onLocalTransportCandidatesGenerated.connect(boost::bind(&IncomingJingleFileTransfer::handleLocalTransportCandidatesGenerated, this, _1)); + +	session->onTransportInfoReceived.connect(boost::bind(&IncomingJingleFileTransfer::handleTransportInfoReceived, this, _1, _2)); +	session->onTransportReplaceReceived.connect(boost::bind(&IncomingJingleFileTransfer::handleTransportReplaceReceived, this, _1, _2)); +	session->onSessionTerminateReceived.connect(boost::bind(&IncomingJingleFileTransfer::handleSessionTerminateReceived, this)); + +	description = initialContent->getDescription<JingleFileTransferDescription>(); +	assert(description); +} + +IncomingJingleFileTransfer::~IncomingJingleFileTransfer() { +	session->onSessionTerminateReceived.disconnect(boost::bind(&IncomingJingleFileTransfer::handleSessionTerminateReceived, this)); +	session->onTransportReplaceReceived.disconnect(boost::bind(&IncomingJingleFileTransfer::handleTransportReplaceReceived, this, _1, _2)); +	session->onTransportInfoReceived.disconnect(boost::bind(&IncomingJingleFileTransfer::handleTransportInfoReceived, this, _1, _2)); + +	candidateGenerator->onLocalTransportCandidatesGenerated.disconnect(boost::bind(&IncomingJingleFileTransfer::handleLocalTransportCandidatesGenerated, this, _1)); +	delete candidateGenerator; +	candidateSelector->onRemoteTransportCandidateSelectFinished.disconnect(boost::bind(&IncomingJingleFileTransfer::handleRemoteTransportCandidateSelectFinished, this, _1)); +	delete candidateSelector;  }  void IncomingJingleFileTransfer::accept(WriteBytestream::ref stream) { +	assert(!stream);  	this->stream = stream; + +	if (JingleIBBTransportPayload::ref ibbTransport = initialContent->getTransport<JingleIBBTransportPayload>()) { +		setActiveTransport(createIBBTransport(ibbTransport)); +		session->accept(); +	} +	else if (JingleS5BTransportPayload::ref s5bTransport = initialContent->getTransport<JingleS5BTransportPayload>()) { +		state = CreatingInitialTransports; +		candidateSelector->addRemoteTransportCandidates(s5bTransport); +		candidateGenerator->generateLocalTransportCandidates(); +	} +	else { +		assert(false); +	} +} + + +void IncomingJingleFileTransfer::handleLocalTransportCandidatesGenerated(JingleTransportPayload::ref candidates) { +	if (state == CreatingInitialTransports) { +		if (!candidates) { +			localTransportCandidateSelectFinished = true; +		} +		session->accept(candidates); +		state = NegotiatingTransport; +		candidateSelector->selectCandidate(); +	} +} + + +void IncomingJingleFileTransfer::handleRemoteTransportCandidateSelectFinished(JingleTransportPayload::ref transport) { +	remoteTransportCandidateSelectFinished = true; +	selectedRemoteTransportCandidate = transport; +	session->sendTransportInfo(contentID, transport); +	checkCandidateSelected(); +} + +void IncomingJingleFileTransfer::checkCandidateSelected() { +	if (localTransportCandidateSelectFinished && remoteTransportCandidateSelectFinished) { +		if (candidateGenerator->isActualCandidate(selectedLocalTransportCandidate) && candidateSelector->isActualCandidate(selectedRemoteTransportCandidate)) { +			if (candidateGenerator->getPriority(selectedLocalTransportCandidate) > candidateSelector->getPriority(selectedRemoteTransportCandidate)) { +				setActiveTransport(candidateGenerator->selectTransport(selectedLocalTransportCandidate)); +			} +			else { +				setActiveTransport(candidateSelector->selectTransport(selectedRemoteTransportCandidate)); +			} +		} +		else if (candidateSelector->isActualCandidate(selectedRemoteTransportCandidate)) { +			setActiveTransport(candidateSelector->selectTransport(selectedRemoteTransportCandidate)); +		} +		else if (candidateGenerator->isActualCandidate(selectedLocalTransportCandidate)) { +			setActiveTransport(candidateGenerator->selectTransport(selectedLocalTransportCandidate)); +		} +		else { +			state = WaitingForFallbackOrTerminate; +		} +	} +} + +void IncomingJingleFileTransfer::setActiveTransport(JingleTransport::ref transport) { +	state = Transferring; +	activeTransport = transport; +	activeTransport->onDataReceived.connect(boost::bind(&IncomingJingleFileTransfer::handleTransportDataReceived, this, _1)); +	activeTransport->start(); +} + +void IncomingJingleFileTransfer::handleSessionTerminateReceived() { +	// TODO +	state = Terminated; +} + +void IncomingJingleFileTransfer::handleTransportDataReceived(const std::vector<unsigned char>& data) { +	stream->write(data); +} + + +void IncomingJingleFileTransfer::handleTransportInfoReceived(const JingleContentID&, JingleTransportPayload::ref transport) { +	localTransportCandidateSelectFinished = true; +	selectedLocalTransportCandidate = transport; +	if (candidateGenerator->isActualCandidate(transport)) { +		candidateSelector->setMinimumPriority(candidateGenerator->getPriority(transport)); +	} +	checkCandidateSelected(); +} + +void IncomingJingleFileTransfer::handleTransportReplaceReceived(const JingleContentID& content, JingleTransportPayload::ref transport) { +	if (JingleIBBTransportPayload::ref ibbTransport = boost::dynamic_pointer_cast<JingleIBBTransportPayload>(transport)) { +		setActiveTransport(createIBBTransport(ibbTransport)); +		session->acceptTransport(content, transport); +	} +	else { +		session->rejectTransport(content, transport); +	} +} + +void IncomingJingleFileTransfer::stopActiveTransport() { +	if (activeTransport) { +		activeTransport->stop(); +		activeTransport->onDataReceived.disconnect(boost::bind(&IncomingJingleFileTransfer::handleTransportDataReceived, this, _1)); +	} +} + +JingleIncomingIBBTransport::ref IncomingJingleFileTransfer::createIBBTransport(JingleIBBTransportPayload::ref ibbTransport) { +	return boost::make_shared<JingleIncomingIBBTransport>(session->getInitiator(), ibbTransport->getSessionID(), description->getOffer()->size, router);  }  } diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.h b/Swiften/FileTransfer/IncomingJingleFileTransfer.h index d69449e..164d868 100644 --- a/Swiften/FileTransfer/IncomingJingleFileTransfer.h +++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.h @@ -8,20 +8,71 @@  #include <boost/shared_ptr.hpp> -#include <Swiften/Jingle/IncomingJingleSession.h> +#include <Swiften/Jingle/JingleSession.h> +#include <Swiften/Jingle/JingleContentID.h>  #include <Swiften/FileTransfer/IncomingFileTransfer.h> +#include <Swiften/FileTransfer/JingleTransport.h> +#include <Swiften/FileTransfer/JingleIncomingIBBTransport.h> +#include <Swiften/Elements/JingleContentPayload.h> +#include <Swiften/Elements/JingleFileTransferDescription.h> +#include <Swiften/Elements/JingleIBBTransportPayload.h>  namespace Swift { +	class IQRouter; +	class RemoteJingleTransportCandidateSelectorFactory; +	class LocalJingleTransportCandidateGeneratorFactory; +	class RemoteJingleTransportCandidateSelector; +	class LocalJingleTransportCandidateGenerator; +  	class IncomingJingleFileTransfer : public IncomingFileTransfer {  		public:  			typedef boost::shared_ptr<IncomingJingleFileTransfer> ref; +			enum State { +				Initial, +				CreatingInitialTransports, +				NegotiatingTransport, +				Transferring, +				WaitingForFallbackOrTerminate, +				Terminated +			}; -			IncomingJingleFileTransfer(IncomingJingleSession::ref session); +			IncomingJingleFileTransfer( +					JingleSession::ref, +					JingleContentPayload::ref content, +					RemoteJingleTransportCandidateSelectorFactory*, +					LocalJingleTransportCandidateGeneratorFactory*, +					IQRouter* router); +			~IncomingJingleFileTransfer();  			virtual void accept(WriteBytestream::ref);  		private: -			IncomingJingleSession::ref session; +			void handleSessionTerminateReceived(); +			void handleTransportReplaceReceived(const JingleContentID&, JingleTransportPayload::ref); +			void handleTransportInfoReceived(const JingleContentID&, JingleTransportPayload::ref); +			void handleLocalTransportCandidatesGenerated(JingleTransportPayload::ref candidates); +			void handleRemoteTransportCandidateSelectFinished(JingleTransportPayload::ref candidate); +			void setActiveTransport(JingleTransport::ref transport); +			void handleTransportDataReceived(const std::vector<unsigned char>& data); +			void stopActiveTransport(); +			void checkCandidateSelected(); +			JingleIncomingIBBTransport::ref createIBBTransport(JingleIBBTransportPayload::ref ibbTransport); + +		private: +			JingleSession::ref session; +			IQRouter* router; +			JingleContentPayload::ref initialContent; +			JingleContentID contentID; +			State state; +			JingleFileTransferDescription::ref description;  			WriteBytestream::ref stream; +			RemoteJingleTransportCandidateSelector* candidateSelector; +			LocalJingleTransportCandidateGenerator* candidateGenerator; +			bool remoteTransportCandidateSelectFinished; +			JingleTransportPayload::ref selectedRemoteTransportCandidate; +			bool localTransportCandidateSelectFinished; +			JingleTransportPayload::ref selectedLocalTransportCandidate; + +			JingleTransport::ref activeTransport;  	};  } diff --git a/Swiften/FileTransfer/JingleIncomingIBBTransport.cpp b/Swiften/FileTransfer/JingleIncomingIBBTransport.cpp new file mode 100644 index 0000000..0ca899f --- /dev/null +++ b/Swiften/FileTransfer/JingleIncomingIBBTransport.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/FileTransfer/JingleIncomingIBBTransport.h> + +namespace Swift { + +JingleIncomingIBBTransport::JingleIncomingIBBTransport(const JID& from, const std::string& id, size_t size, IQRouter* router) : ibbSession(from, id, size, router) { +	ibbSession.onDataReceived.connect(boost::ref(onDataReceived)); +} + +void JingleIncomingIBBTransport::start() { +	ibbSession.start(); +} + +void JingleIncomingIBBTransport::stop() { +	ibbSession.stop(); +} + +} diff --git a/Swiften/FileTransfer/JingleIncomingIBBTransport.h b/Swiften/FileTransfer/JingleIncomingIBBTransport.h new file mode 100644 index 0000000..e2fa485 --- /dev/null +++ b/Swiften/FileTransfer/JingleIncomingIBBTransport.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> + +#include <Swiften/FileTransfer/JingleTransport.h> +#include <Swiften/FileTransfer/IBBReceiveSession.h> + +namespace Swift { +	class JingleIncomingIBBTransport : public JingleTransport { +		public: +			typedef boost::shared_ptr<JingleIncomingIBBTransport> ref; + +			JingleIncomingIBBTransport(const JID& from, const std::string& id, size_t size, IQRouter* router); + +			virtual void start(); +			virtual void stop(); + +		private: +			IBBReceiveSession ibbSession; +	}; +} diff --git a/Swiften/FileTransfer/JingleTransport.cpp b/Swiften/FileTransfer/JingleTransport.cpp new file mode 100644 index 0000000..c507922 --- /dev/null +++ b/Swiften/FileTransfer/JingleTransport.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/FileTransfer/JingleTransport.h> + +namespace Swift { + +JingleTransport::~JingleTransport() { + +} + +} diff --git a/Swiften/FileTransfer/JingleTransport.h b/Swiften/FileTransfer/JingleTransport.h new file mode 100644 index 0000000..1d163d0 --- /dev/null +++ b/Swiften/FileTransfer/JingleTransport.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> + +#include <Swiften/Base/boost_bsignals.h> + +namespace Swift { +	class JingleTransport { +		public: +			typedef boost::shared_ptr<JingleTransport> ref; + +			virtual ~JingleTransport(); + +			virtual void start() = 0; +			virtual void stop() = 0; + +			boost::signal<void (const std::vector<unsigned char>&)> onDataReceived; +	}; +} diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp new file mode 100644 index 0000000..852902b --- /dev/null +++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h> + +namespace Swift { + +LocalJingleTransportCandidateGenerator::~LocalJingleTransportCandidateGenerator() { +} + +} diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h new file mode 100644 index 0000000..c111005 --- /dev/null +++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGenerator.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Base/boost_bsignals.h> + +#include <Swiften/Elements/JingleTransportPayload.h> +#include <Swiften/FileTransfer/JingleTransport.h> + +namespace Swift { +	class LocalJingleTransportCandidateGenerator { +		public: +			virtual ~LocalJingleTransportCandidateGenerator(); + +			virtual void generateLocalTransportCandidates() = 0; + +			virtual bool isActualCandidate(JingleTransportPayload::ref) = 0; +			virtual int getPriority(JingleTransportPayload::ref) = 0; +			virtual JingleTransport::ref selectTransport(JingleTransportPayload::ref) = 0; + +			boost::signal<void (JingleTransportPayload::ref)> onLocalTransportCandidatesGenerated; +	}; +} diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.cpp b/Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.cpp new file mode 100644 index 0000000..a1e3874 --- /dev/null +++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h> + +namespace Swift { + +LocalJingleTransportCandidateGeneratorFactory::~LocalJingleTransportCandidateGeneratorFactory() { +} + +} diff --git a/Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h b/Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h new file mode 100644 index 0000000..c969fc7 --- /dev/null +++ b/Swiften/FileTransfer/LocalJingleTransportCandidateGeneratorFactory.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +namespace Swift { +	class LocalJingleTransportCandidateGenerator; + +	class LocalJingleTransportCandidateGeneratorFactory { +		public: +			virtual ~LocalJingleTransportCandidateGeneratorFactory(); + +			virtual LocalJingleTransportCandidateGenerator* createCandidateGenerator() = 0; +	}; +} diff --git a/Swiften/FileTransfer/OutgoingFileTransfer.cpp b/Swiften/FileTransfer/OutgoingFileTransfer.cpp index 32f7e17..94d4348 100644 --- a/Swiften/FileTransfer/OutgoingFileTransfer.cpp +++ b/Swiften/FileTransfer/OutgoingFileTransfer.cpp @@ -4,75 +4,11 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/FileTransfer/OutgoingFileTransfer.h" - -#include <boost/bind.hpp> - -#include "Swiften/FileTransfer/StreamInitiationRequest.h" -#include "Swiften/FileTransfer/BytestreamsRequest.h" -#include "Swiften/FileTransfer/SOCKS5BytestreamServer.h" -#include "Swiften/FileTransfer/IBBSendSession.h" +#include <Swiften/FileTransfer/OutgoingFileTransfer.h>  namespace Swift { -OutgoingFileTransfer::OutgoingFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer) : id(id), from(from), to(to), name(name), size(size), description(description), bytestream(bytestream), iqRouter(iqRouter), socksServer(socksServer) { -} - -void OutgoingFileTransfer::start() { -	StreamInitiation::ref streamInitiation(new StreamInitiation()); -	streamInitiation->setID(id); -	streamInitiation->setFileInfo(StreamInitiationFileInfo(name, description, size)); -	//streamInitiation->addProvidedMethod("http://jabber.org/protocol/bytestreams"); -	streamInitiation->addProvidedMethod("http://jabber.org/protocol/ibb"); -	StreamInitiationRequest::ref request = StreamInitiationRequest::create(to, streamInitiation, iqRouter); -	request->onResponse.connect(boost::bind(&OutgoingFileTransfer::handleStreamInitiationRequestResponse, this, _1, _2)); -	request->send(); -} - -void OutgoingFileTransfer::stop() { -} - -void OutgoingFileTransfer::handleStreamInitiationRequestResponse(StreamInitiation::ref response, ErrorPayload::ref error) { -	if (error) { -		finish(FileTransferError()); -	} -	else { -		if (response->getRequestedMethod() == "http://jabber.org/protocol/bytestreams") { -			socksServer->addBytestream(id, from, to, bytestream);  -			Bytestreams::ref bytestreams(new Bytestreams()); -			bytestreams->setStreamID(id); -			HostAddressPort addressPort = socksServer->getAddressPort(); -			bytestreams->addStreamHost(Bytestreams::StreamHost(addressPort.getAddress().toString(), from, addressPort.getPort())); -			BytestreamsRequest::ref request = BytestreamsRequest::create(to, bytestreams, iqRouter); -			request->onResponse.connect(boost::bind(&OutgoingFileTransfer::handleBytestreamsRequestResponse, this, _1, _2)); -			request->send(); -		} -		else if (response->getRequestedMethod() == "http://jabber.org/protocol/ibb") { -			ibbSession = boost::shared_ptr<IBBSendSession>(new IBBSendSession(id, to, bytestream, iqRouter)); -			ibbSession->onFinished.connect(boost::bind(&OutgoingFileTransfer::handleIBBSessionFinished, this, _1)); -			ibbSession->start(); -		} -	} -} - -void OutgoingFileTransfer::handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref error) { -	if (error) { -		finish(FileTransferError()); -	} -	//socksServer->onTransferFinished.connect(); -} - -void OutgoingFileTransfer::finish(boost::optional<FileTransferError> error) { -	if (ibbSession) { -		ibbSession->onFinished.disconnect(boost::bind(&OutgoingFileTransfer::handleIBBSessionFinished, this, _1)); -		ibbSession.reset(); -	} -	socksServer->removeBytestream(id, from, to);  -	onFinished(error); -} - -void OutgoingFileTransfer::handleIBBSessionFinished(boost::optional<FileTransferError> error) { -	finish(error); +OutgoingFileTransfer::~OutgoingFileTransfer() {  }  } diff --git a/Swiften/FileTransfer/OutgoingFileTransfer.h b/Swiften/FileTransfer/OutgoingFileTransfer.h index a694c13..a8c1e81 100644 --- a/Swiften/FileTransfer/OutgoingFileTransfer.h +++ b/Swiften/FileTransfer/OutgoingFileTransfer.h @@ -6,47 +6,12 @@  #pragma once -#include <boost/shared_ptr.hpp> - -#include "Swiften/FileTransfer/ReadBytestream.h" -#include "Swiften/Base/boost_bsignals.h" -#include "Swiften/FileTransfer/FileTransferError.h" -#include "Swiften/FileTransfer/SOCKS5BytestreamServer.h" -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/StreamInitiation.h" -#include "Swiften/Elements/Bytestreams.h" -#include "Swiften/Elements/ErrorPayload.h" -#include "Swiften/FileTransfer/IBBSendSession.h" -  namespace Swift { -	class IQRouter; -	class SOCKS5BytestreamServer; -  	class OutgoingFileTransfer {  		public: -			OutgoingFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer); - -			void start(); -			void stop(); - -			boost::signal<void (const boost::optional<FileTransferError>&)> onFinished; - -		private: -			void handleStreamInitiationRequestResponse(StreamInitiation::ref, ErrorPayload::ref); -			void handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref); -			void finish(boost::optional<FileTransferError> error); -			void handleIBBSessionFinished(boost::optional<FileTransferError> error); +			virtual ~OutgoingFileTransfer(); -		private: -			std::string id; -			JID from; -			JID to; -			std::string name; -			int size; -			std::string description; -			boost::shared_ptr<ReadBytestream> bytestream; -			IQRouter* iqRouter; -			SOCKS5BytestreamServer* socksServer; -			boost::shared_ptr<IBBSendSession> ibbSession; +			virtual void start() = 0; +			virtual void stop() = 0;  	};  } diff --git a/Swiften/FileTransfer/OutgoingSIFileTransfer.cpp b/Swiften/FileTransfer/OutgoingSIFileTransfer.cpp new file mode 100644 index 0000000..2ed3a9d --- /dev/null +++ b/Swiften/FileTransfer/OutgoingSIFileTransfer.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swiften/FileTransfer/OutgoingSIFileTransfer.h" + +#include <boost/bind.hpp> + +#include "Swiften/FileTransfer/StreamInitiationRequest.h" +#include "Swiften/FileTransfer/BytestreamsRequest.h" +#include "Swiften/FileTransfer/SOCKS5BytestreamServer.h" +#include "Swiften/FileTransfer/IBBSendSession.h" + +namespace Swift { + +OutgoingSIFileTransfer::OutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer) : id(id), from(from), to(to), name(name), size(size), description(description), bytestream(bytestream), iqRouter(iqRouter), socksServer(socksServer) { +} + +void OutgoingSIFileTransfer::start() { +	StreamInitiation::ref streamInitiation(new StreamInitiation()); +	streamInitiation->setID(id); +	streamInitiation->setFileInfo(StreamInitiationFileInfo(name, description, size)); +	//streamInitiation->addProvidedMethod("http://jabber.org/protocol/bytestreams"); +	streamInitiation->addProvidedMethod("http://jabber.org/protocol/ibb"); +	StreamInitiationRequest::ref request = StreamInitiationRequest::create(to, streamInitiation, iqRouter); +	request->onResponse.connect(boost::bind(&OutgoingSIFileTransfer::handleStreamInitiationRequestResponse, this, _1, _2)); +	request->send(); +} + +void OutgoingSIFileTransfer::stop() { +} + +void OutgoingSIFileTransfer::handleStreamInitiationRequestResponse(StreamInitiation::ref response, ErrorPayload::ref error) { +	if (error) { +		finish(FileTransferError()); +	} +	else { +		if (response->getRequestedMethod() == "http://jabber.org/protocol/bytestreams") { +			socksServer->addBytestream(id, from, to, bytestream);  +			Bytestreams::ref bytestreams(new Bytestreams()); +			bytestreams->setStreamID(id); +			HostAddressPort addressPort = socksServer->getAddressPort(); +			bytestreams->addStreamHost(Bytestreams::StreamHost(addressPort.getAddress().toString(), from, addressPort.getPort())); +			BytestreamsRequest::ref request = BytestreamsRequest::create(to, bytestreams, iqRouter); +			request->onResponse.connect(boost::bind(&OutgoingSIFileTransfer::handleBytestreamsRequestResponse, this, _1, _2)); +			request->send(); +		} +		else if (response->getRequestedMethod() == "http://jabber.org/protocol/ibb") { +			ibbSession = boost::shared_ptr<IBBSendSession>(new IBBSendSession(id, to, bytestream, iqRouter)); +			ibbSession->onFinished.connect(boost::bind(&OutgoingSIFileTransfer::handleIBBSessionFinished, this, _1)); +			ibbSession->start(); +		} +	} +} + +void OutgoingSIFileTransfer::handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref error) { +	if (error) { +		finish(FileTransferError()); +	} +	//socksServer->onTransferFinished.connect(); +} + +void OutgoingSIFileTransfer::finish(boost::optional<FileTransferError> error) { +	if (ibbSession) { +		ibbSession->onFinished.disconnect(boost::bind(&OutgoingSIFileTransfer::handleIBBSessionFinished, this, _1)); +		ibbSession.reset(); +	} +	socksServer->removeBytestream(id, from, to);  +	onFinished(error); +} + +void OutgoingSIFileTransfer::handleIBBSessionFinished(boost::optional<FileTransferError> error) { +	finish(error); +} + +} diff --git a/Swiften/FileTransfer/OutgoingSIFileTransfer.h b/Swiften/FileTransfer/OutgoingSIFileTransfer.h new file mode 100644 index 0000000..cdf988f --- /dev/null +++ b/Swiften/FileTransfer/OutgoingSIFileTransfer.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> + +#include <Swiften/FileTransfer/OutgoingFileTransfer.h> +#include "Swiften/FileTransfer/ReadBytestream.h" +#include "Swiften/Base/boost_bsignals.h" +#include "Swiften/FileTransfer/FileTransferError.h" +#include "Swiften/FileTransfer/SOCKS5BytestreamServer.h" +#include "Swiften/JID/JID.h" +#include "Swiften/Elements/StreamInitiation.h" +#include "Swiften/Elements/Bytestreams.h" +#include "Swiften/Elements/ErrorPayload.h" +#include "Swiften/FileTransfer/IBBSendSession.h" + +namespace Swift { +	class IQRouter; +	class SOCKS5BytestreamServer; + +	class OutgoingSIFileTransfer : public OutgoingFileTransfer { +		public: +			OutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer); + +			virtual void start(); +			virtual void stop(); + +			boost::signal<void (const boost::optional<FileTransferError>&)> onFinished; + +		private: +			void handleStreamInitiationRequestResponse(StreamInitiation::ref, ErrorPayload::ref); +			void handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref); +			void finish(boost::optional<FileTransferError> error); +			void handleIBBSessionFinished(boost::optional<FileTransferError> error); + +		private: +			std::string id; +			JID from; +			JID to; +			std::string name; +			int size; +			std::string description; +			boost::shared_ptr<ReadBytestream> bytestream; +			IQRouter* iqRouter; +			SOCKS5BytestreamServer* socksServer; +			boost::shared_ptr<IBBSendSession> ibbSession; +	}; +} diff --git a/Swiften/FileTransfer/ReadBytestream.h b/Swiften/FileTransfer/ReadBytestream.h index 4da2bc2..529545e 100644 --- a/Swiften/FileTransfer/ReadBytestream.h +++ b/Swiften/FileTransfer/ReadBytestream.h @@ -6,13 +6,13 @@  #pragma once -#include "Swiften/Base/ByteArray.h" +#include <vector>  namespace Swift {  	class ReadBytestream {  		public:  			virtual ~ReadBytestream(); -			virtual ByteArray read(size_t size) = 0; +			virtual std::vector<unsigned char> read(size_t size) = 0;  			virtual bool isFinished() const = 0;  	};  } diff --git a/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.cpp b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.cpp new file mode 100644 index 0000000..338f221 --- /dev/null +++ b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h> + +namespace Swift { + +RemoteJingleTransportCandidateSelector::~RemoteJingleTransportCandidateSelector() { +} + +} diff --git a/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h new file mode 100644 index 0000000..b12b06b --- /dev/null +++ b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelector.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Base/boost_bsignals.h> + +#include <Swiften/Elements/JingleTransportPayload.h> +#include <Swiften/FileTransfer/JingleTransport.h> + +namespace Swift { +	class RemoteJingleTransportCandidateSelector { +		public: +			virtual ~RemoteJingleTransportCandidateSelector(); + +			virtual void addRemoteTransportCandidates(JingleTransportPayload::ref) = 0; +			virtual void selectCandidate() = 0; +			virtual void setMinimumPriority(int) = 0; + +			virtual bool isActualCandidate(JingleTransportPayload::ref) = 0; +			virtual int getPriority(JingleTransportPayload::ref) = 0; +			virtual JingleTransport::ref selectTransport(JingleTransportPayload::ref) = 0; + +			boost::signal<void (JingleTransportPayload::ref)> onRemoteTransportCandidateSelectFinished; +	}; +} diff --git a/Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.cpp b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.cpp new file mode 100644 index 0000000..36b7cba --- /dev/null +++ b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h> + +namespace Swift { + +RemoteJingleTransportCandidateSelectorFactory::~RemoteJingleTransportCandidateSelectorFactory() { +} + +} diff --git a/Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h new file mode 100644 index 0000000..caa3097 --- /dev/null +++ b/Swiften/FileTransfer/RemoteJingleTransportCandidateSelectorFactory.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +namespace Swift { +	class RemoteJingleTransportCandidateSelector; + +	class RemoteJingleTransportCandidateSelectorFactory { +		public: +			virtual ~RemoteJingleTransportCandidateSelectorFactory(); + +			virtual RemoteJingleTransportCandidateSelector* createCandidateSelector() = 0; +	}; +} diff --git a/Swiften/FileTransfer/SConscript b/Swiften/FileTransfer/SConscript index ea9e7bb..24fc9e8 100644 --- a/Swiften/FileTransfer/SConscript +++ b/Swiften/FileTransfer/SConscript @@ -1,10 +1,17 @@ -Import("swiften_env") +Import("swiften_env", "env")  sources = [  		"OutgoingFileTransfer.cpp", +		"OutgoingSIFileTransfer.cpp",  		"IncomingFileTransfer.cpp",  		"IncomingJingleFileTransfer.cpp", -		"IncomingFileTransferManager.cpp",	 +		"IncomingFileTransferManager.cpp", +		"RemoteJingleTransportCandidateSelector.cpp", +		"RemoteJingleTransportCandidateSelectorFactory.cpp", +		"LocalJingleTransportCandidateGenerator.cpp", +		"LocalJingleTransportCandidateGeneratorFactory.cpp", +		"JingleTransport.cpp", +		"JingleIncomingIBBTransport.cpp",  		"ReadBytestream.cpp",  		"WriteBytestream.cpp",  		"FileReadBytestream.cpp", @@ -17,3 +24,9 @@ sources = [  	]  swiften_env.Append(SWIFTEN_OBJECTS = swiften_env.SwiftenObject(sources)) + +env.Append(UNITTEST_SOURCES = [ +			File("UnitTest/SOCKS5BytestreamServerSessionTest.cpp"), +			File("UnitTest/IBBSendSessionTest.cpp"), +			File("UnitTest/IBBReceiveSessionTest.cpp"), +	]) diff --git a/Swiften/FileTransfer/UnitTest/IBBReceiveSessionTest.cpp b/Swiften/FileTransfer/UnitTest/IBBReceiveSessionTest.cpp new file mode 100644 index 0000000..88d9cd4 --- /dev/null +++ b/Swiften/FileTransfer/UnitTest/IBBReceiveSessionTest.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <vector> +#include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Base/ByteArray.h> +#include "Swiften/FileTransfer/IBBReceiveSession.h" +#include "Swiften/Queries/IQRouter.h" +#include "Swiften/Client/DummyStanzaChannel.h" + +using namespace Swift; + +class IBBReceiveSessionTest : public CppUnit::TestFixture { +		CPPUNIT_TEST_SUITE(IBBReceiveSessionTest); +		CPPUNIT_TEST(testOpen); +		CPPUNIT_TEST(testReceiveData); +		CPPUNIT_TEST(testReceiveMultipleData); +		CPPUNIT_TEST(testReceiveDataForOtherSession); +		CPPUNIT_TEST(testReceiveDataOutOfOrder); +		CPPUNIT_TEST(testReceiveLastData); +		CPPUNIT_TEST(testReceiveClose); +		CPPUNIT_TEST(testStopWhileActive); +		CPPUNIT_TEST_SUITE_END(); + +	public: +		void setUp() { +			stanzaChannel = new DummyStanzaChannel(); +			iqRouter = new IQRouter(stanzaChannel); +		} + +		void tearDown() { +			delete iqRouter; +			delete stanzaChannel; +		} + +		void testOpen() { +			std::auto_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); +			testling->start(); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + +			CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(0, "id-open")); +			CPPUNIT_ASSERT(!finished); + +			testling->stop(); +		} + +		void testReceiveData() { +			std::auto_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); +			testling->start(); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, ByteArray::create("abc")), "foo@bar.com/baz", "id-a")); + +			CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(1, "id-a")); +			CPPUNIT_ASSERT(ByteArray::create("abc") == receivedData); +			CPPUNIT_ASSERT(!finished); + +			testling->stop(); +		} + +		void testReceiveMultipleData() { +			std::auto_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); +			testling->start(); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, ByteArray::create("abc")), "foo@bar.com/baz", "id-a")); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 1, ByteArray::create("def")), "foo@bar.com/baz", "id-b")); + +			CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(2, "id-b")); +			CPPUNIT_ASSERT(ByteArray::create("abcdef") == receivedData); +			CPPUNIT_ASSERT(!finished); + +			testling->stop(); +		} + +		void testReceiveDataForOtherSession() { +			std::auto_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); +			testling->start(); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("othersession", 0, ByteArray::create("abc")), "foo@bar.com/baz", "id-a")); + +			CPPUNIT_ASSERT(stanzaChannel->isErrorAtIndex(1, "id-a")); + +			testling->stop(); +		} + +		void testReceiveDataOutOfOrder() { +			std::auto_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); +			testling->start(); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, ByteArray::create("abc")), "foo@bar.com/baz", "id-a")); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, ByteArray::create("def")), "foo@bar.com/baz", "id-b")); + +			CPPUNIT_ASSERT(stanzaChannel->isErrorAtIndex(2, "id-b")); +			CPPUNIT_ASSERT(finished); +			CPPUNIT_ASSERT(error); + +			testling->stop(); +		} + +		void testReceiveLastData() { +			std::auto_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession", 6)); +			testling->start(); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 0, ByteArray::create("abc")), "foo@bar.com/baz", "id-a")); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBData("mysession", 1, ByteArray::create("def")), "foo@bar.com/baz", "id-b")); + +			CPPUNIT_ASSERT(stanzaChannel->isResultAtIndex(2, "id-b")); +			CPPUNIT_ASSERT(ByteArray::create("abcdef") == receivedData); +			CPPUNIT_ASSERT(finished); +			CPPUNIT_ASSERT(!error); + +			testling->stop(); +		} + +		void testReceiveClose() { +			std::auto_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); +			testling->start(); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBClose("mysession"), "foo@bar.com/baz", "id-close")); + +			CPPUNIT_ASSERT(finished); +			CPPUNIT_ASSERT(error); + +			testling->stop(); +		} + +		void testStopWhileActive() { +			std::auto_ptr<IBBReceiveSession> testling(createSession("foo@bar.com/baz", "mysession")); +			testling->start(); +			stanzaChannel->onIQReceived(createIBBRequest(IBB::createIBBOpen("mysession", 0x10), "foo@bar.com/baz", "id-open")); + +			testling->stop(); + +			CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(1, JID("foo@bar.com/baz"), IQ::Set)); +			IBB::ref ibb = stanzaChannel->sentStanzas[1]->getPayload<IBB>(); +			CPPUNIT_ASSERT_EQUAL(IBB::Close, ibb->getAction()); +			CPPUNIT_ASSERT_EQUAL(std::string("mysession"), ibb->getStreamID()); +			CPPUNIT_ASSERT(finished); +			CPPUNIT_ASSERT(!error); +		} + +	private: +		IQ::ref createIBBRequest(IBB::ref ibb, const JID& from, const std::string& id) { +			IQ::ref request = IQ::createRequest(IQ::Set, JID("baz@fum.com/dum"), id, ibb); +			request->setFrom(from); +			return request; +		} + +		IBBReceiveSession* createSession(const std::string& from, const std::string& id, size_t size = 0x1000) { +			IBBReceiveSession* session = new IBBReceiveSession(id, JID(from), size, iqRouter); +			session->onDataReceived.connect(boost::bind(&IBBReceiveSessionTest::handleDataReceived, this, _1)); +			session->onFinished.connect(boost::bind(&IBBReceiveSessionTest::handleFinished, this, _1)); +			return session; +		} + + +		void handleFinished(boost::optional<FileTransferError> error) { +			finished = true; +			this->error = error; +		} + +		void handleDataReceived(const std::vector<unsigned char>& data) { +			receivedData.insert(receivedData.end(), data.begin(), data.end()); +		} + +	private: +		DummyStanzaChannel* stanzaChannel; +		IQRouter* iqRouter; +		bool finished; +		boost::optional<FileTransferError> error; +		std::vector<unsigned char> receivedData; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(IBBReceiveSessionTest); diff --git a/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp b/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp index 0cd273a..32df34b 100644 --- a/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp +++ b/Swiften/FileTransfer/UnitTest/IBBSendSessionTest.cpp @@ -4,13 +4,12 @@   * See Documentation/Licenses/GPLv3.txt for more information.   */ -#include "Swiften/Base/ByteArray.h" -  #include <cppunit/extensions/HelperMacros.h>  #include <cppunit/extensions/TestFactoryRegistry.h>  #include <vector>  #include <boost/bind.hpp> +#include "Swiften/Base/ByteArray.h"  #include "Swiften/FileTransfer/IBBSendSession.h"  #include "Swiften/FileTransfer/ByteArrayReadBytestream.h"  #include "Swiften/Queries/IQRouter.h" @@ -33,7 +32,7 @@ class IBBSendSessionTest : public CppUnit::TestFixture {  		void setUp() {  			stanzaChannel = new DummyStanzaChannel();  			iqRouter = new IQRouter(stanzaChannel); -			bytestream = boost::shared_ptr<ByteArrayReadBytestream>(new ByteArrayReadBytestream(ByteArray("abcdefg"))); +			bytestream = boost::shared_ptr<ByteArrayReadBytestream>(new ByteArrayReadBytestream(ByteArray::create("abcdefg")));  		}  		void tearDown() { @@ -66,7 +65,7 @@ class IBBSendSessionTest : public CppUnit::TestFixture {  			CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(1, JID("foo@bar.com/baz"), IQ::Set));  			IBB::ref ibb = stanzaChannel->sentStanzas[1]->getPayload<IBB>();  			CPPUNIT_ASSERT_EQUAL(IBB::Data, ibb->getAction()); -			CPPUNIT_ASSERT_EQUAL(ByteArray("abc"), ibb->getData()); +			CPPUNIT_ASSERT(ByteArray::create("abc") == ibb->getData());  			CPPUNIT_ASSERT_EQUAL(0, ibb->getSequenceNumber());  			CPPUNIT_ASSERT_EQUAL(std::string("myid"), ibb->getStreamID());  		} @@ -82,7 +81,7 @@ class IBBSendSessionTest : public CppUnit::TestFixture {  			CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<IBB>(2, JID("foo@bar.com/baz"), IQ::Set));  			IBB::ref ibb = stanzaChannel->sentStanzas[2]->getPayload<IBB>();  			CPPUNIT_ASSERT_EQUAL(IBB::Data, ibb->getAction()); -			CPPUNIT_ASSERT_EQUAL(ByteArray("def"), ibb->getData()); +			CPPUNIT_ASSERT(ByteArray::create("def") == ibb->getData());  			CPPUNIT_ASSERT_EQUAL(1, ibb->getSequenceNumber());  			CPPUNIT_ASSERT_EQUAL(std::string("myid"), ibb->getStreamID());  		} diff --git a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp index c6d246d..1c1a246 100644 --- a/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp +++ b/Swiften/FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp @@ -35,7 +35,7 @@ class SOCKS5BytestreamServerSessionTest : public CppUnit::TestFixture {  			eventLoop = new DummyEventLoop();  			connection = boost::shared_ptr<DummyConnection>(new DummyConnection(eventLoop));  			connection->onDataSent.connect(boost::bind(&SOCKS5BytestreamServerSessionTest::handleDataWritten, this, _1)); -			stream1 = boost::shared_ptr<ByteArrayReadBytestream>(new ByteArrayReadBytestream(ByteArray("abcdefg"))); +			stream1 = boost::shared_ptr<ByteArrayReadBytestream>(new ByteArrayReadBytestream(ByteArray::create("abcdefg")));  		}  		void tearDown() { @@ -47,20 +47,20 @@ class SOCKS5BytestreamServerSessionTest : public CppUnit::TestFixture {  			std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession());  			StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); -			receive(ByteArray("\x05\x02\x01\x02")); +			receive(ByteArray::create("\x05\x02\x01\x02")); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\x05\x00", 2), receivedData); +			CPPUNIT_ASSERT(ByteArray::create("\x05\x00", 2) == receivedData);  		}  		void testAuthenticate_Chunked() {  			std::auto_ptr<SOCKS5BytestreamServerSession> testling(createSession());  			StartStopper<SOCKS5BytestreamServerSession> stopper(testling.get()); -			receive(ByteArray("\x05\x02\x01")); +			receive(ByteArray::create("\x05\x02\x01")); -			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedData.getSize())); -			receive(ByteArray("\x01")); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\x05\x00", 2), receivedData); +			CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(receivedData.size())); +			receive(ByteArray::create("\x01")); +			CPPUNIT_ASSERT(ByteArray::create("\x05\x00", 2) == receivedData);  		}  		void testRequest() { @@ -70,8 +70,8 @@ class SOCKS5BytestreamServerSessionTest : public CppUnit::TestFixture {  			authenticate();  			ByteArray hostname("abcdef"); -			receive(ByteArray("\x05\x01\x00\x03", 4) + hostname.getSize() + hostname + ByteArray("\x00\x00", 2)); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\x05\x00\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13), ByteArray(receivedData.getData(), 13)); +			receive(ByteArray(ByteArray::create("\x05\x01\x00\x03", 4)) + hostname.getSize() + hostname + ByteArray::create("\x00\x00", 2)); +			CPPUNIT_ASSERT(ByteArray::create("\x05\x00\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13) == ByteArray::create(&receivedData[0], 13));  		}  		void testRequest_UnknownBytestream() { @@ -80,8 +80,8 @@ class SOCKS5BytestreamServerSessionTest : public CppUnit::TestFixture {  			authenticate();  			ByteArray hostname("abcdef"); -			receive(ByteArray("\x05\x01\x00\x03", 4) + hostname.getSize() + hostname + ByteArray("\x00\x00", 2)); -			CPPUNIT_ASSERT_EQUAL(ByteArray("\x05\x04\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13), receivedData); +			receive(ByteArray(ByteArray::create("\x05\x01\x00\x03", 4)) + hostname.getSize() + hostname + ByteArray::create("\x00\x00", 2)); +			CPPUNIT_ASSERT(ByteArray::create("\x05\x04\x00\x03\x06\x61\x62\x63\x64\x65\x66\x00\x00", 13) == receivedData);  		}  		void testReceiveData() { @@ -93,7 +93,7 @@ class SOCKS5BytestreamServerSessionTest : public CppUnit::TestFixture {  			eventLoop->processEvents();  			skipHeader("abcdef"); -			CPPUNIT_ASSERT_EQUAL(ByteArray("abcdefg"), receivedData); +			CPPUNIT_ASSERT(ByteArray::create("abcdefg") == receivedData);  			CPPUNIT_ASSERT_EQUAL(2, receivedDataChunks);  		} @@ -107,7 +107,7 @@ class SOCKS5BytestreamServerSessionTest : public CppUnit::TestFixture {  			eventLoop->processEvents();  			skipHeader("abcdef"); -			CPPUNIT_ASSERT_EQUAL(ByteArray("abcdefg"), receivedData); +			CPPUNIT_ASSERT(ByteArray::create("abcdefg") == receivedData);  			CPPUNIT_ASSERT_EQUAL(4, receivedDataChunks);  		} @@ -118,23 +118,23 @@ class SOCKS5BytestreamServerSessionTest : public CppUnit::TestFixture {  		}  		void authenticate() { -			receive(ByteArray("\x05\x02\x01\x02")); +			receive(ByteArray::create("\x05\x02\x01\x02"));  			receivedData.clear();  			receivedDataChunks = 0;  		}  		void request(const std::string& hostname) { -			receive(ByteArray("\x05\x01\x00\x03", 4) + hostname.size() + hostname + ByteArray("\x00\x00", 2)); +			receive(ByteArray(ByteArray::create("\x05\x01\x00\x03", 4)) + hostname.size() + hostname + ByteArray::create("\x00\x00", 2));  		}  		void skipHeader(const std::string& hostname) {  			int headerSize = 7 + hostname.size(); -			receivedData = ByteArray(receivedData.getData() + headerSize, receivedData.getSize() - headerSize); +			receivedData = ByteArray::create(&receivedData[headerSize], receivedData.size() - headerSize);  		}  		void handleDataWritten(const ByteArray& data) { -			receivedData += data; +			receivedData.insert(receivedData.end(), data.begin(), data.end());  			receivedDataChunks++;  		} @@ -148,7 +148,7 @@ class SOCKS5BytestreamServerSessionTest : public CppUnit::TestFixture {  		DummyEventLoop* eventLoop;  		SOCKS5BytestreamRegistry bytestreams;  		boost::shared_ptr<DummyConnection> connection; -		ByteArray receivedData; +		std::vector<unsigned char> receivedData;  		int receivedDataChunks;  		boost::shared_ptr<ByteArrayReadBytestream> stream1;  }; diff --git a/Swiften/FileTransfer/WriteBytestream.h b/Swiften/FileTransfer/WriteBytestream.h index 1dc791c..c27aeff 100644 --- a/Swiften/FileTransfer/WriteBytestream.h +++ b/Swiften/FileTransfer/WriteBytestream.h @@ -7,8 +7,7 @@  #pragma once  #include <boost/shared_ptr.hpp> - -#include "Swiften/Base/ByteArray.h" +#include <vector>  namespace Swift {  	class WriteBytestream { @@ -17,6 +16,6 @@ namespace Swift {  			virtual ~WriteBytestream(); -			virtual void write(const ByteArray&) = 0; +			virtual void write(const std::vector<unsigned char>&) = 0;  	};  } diff --git a/Swiften/Jingle/IncomingJingleSession.cpp b/Swiften/Jingle/IncomingJingleSession.cpp deleted file mode 100644 index b18d9d3..0000000 --- a/Swiften/Jingle/IncomingJingleSession.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2010 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#include <Swiften/Jingle/IncomingJingleSession.h> - -namespace Swift { - -IncomingJingleSession::IncomingJingleSession(const std::string& id, const std::vector<JingleContent::ref>& contents) : JingleSession(id, contents) { - -} - -} diff --git a/Swiften/Jingle/IncomingJingleSession.h b/Swiften/Jingle/IncomingJingleSession.h deleted file mode 100644 index 64816f6..0000000 --- a/Swiften/Jingle/IncomingJingleSession.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2011 Remko Tronçon - * Licensed under the GNU General Public License v3. - * See Documentation/Licenses/GPLv3.txt for more information. - */ - -#pragma once - -#include <boost/shared_ptr.hpp> - -#include <Swiften/Jingle/JingleSession.h> - -namespace Swift { -	class IncomingJingleSession : public JingleSession { -		public: -			IncomingJingleSession(const std::string& id, const std::vector<JingleContent::ref>& contents); - -			typedef boost::shared_ptr<IncomingJingleSession> ref; -	}; -} diff --git a/Swiften/Jingle/IncomingJingleSessionHandler.h b/Swiften/Jingle/IncomingJingleSessionHandler.h index 5bf9237..4d22a4e 100644 --- a/Swiften/Jingle/IncomingJingleSessionHandler.h +++ b/Swiften/Jingle/IncomingJingleSessionHandler.h @@ -6,13 +6,13 @@  #pragma once -#include <Swiften/Jingle/IncomingJingleSession.h> +#include <Swiften/Jingle/JingleSession.h>  namespace Swift {  	class IncomingJingleSessionHandler {  		public:  			virtual ~IncomingJingleSessionHandler(); -			virtual bool handleIncomingJingleSession(IncomingJingleSession::ref) = 0; +			virtual bool handleIncomingJingleSession(JingleSession::ref, const std::vector<JingleContentPayload::ref>& contents) = 0;  	};  } diff --git a/Swiften/Jingle/Jingle.h b/Swiften/Jingle/Jingle.h new file mode 100644 index 0000000..ba4dfe3 --- /dev/null +++ b/Swiften/Jingle/Jingle.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <vector> + +#include <Swiften/Elements/JingleContentPayload.h> + +namespace Swift { +	namespace Jingle { +		template<typename T> +		JingleContentPayload::ref getContentWithDescription(const std::vector<JingleContentPayload::ref>& contents) { +			for (size_t i = 0; i < contents.size(); ++i) { +				if (contents[i]->getDescription<T>()) { +					return contents[i]; +				} +			} +			return JingleContentPayload::ref(); +		} +	} +} diff --git a/Swiften/Jingle/JingleContentID.h b/Swiften/Jingle/JingleContentID.h new file mode 100644 index 0000000..8d75581 --- /dev/null +++ b/Swiften/Jingle/JingleContentID.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <string> + +#include <Swiften/Elements/JingleContentPayload.h> + +namespace Swift { +	class JingleContentID { +		public: +			JingleContentID(const std::string& name, JingleContentPayload::Creator creator) : name(name), creator(creator) { +			} + +		private: +			std::string name; +			JingleContentPayload::Creator creator; +	}; +} diff --git a/Swiften/Jingle/JingleResponder.cpp b/Swiften/Jingle/JingleResponder.cpp index 2397e63..198f9a2 100644 --- a/Swiften/Jingle/JingleResponder.cpp +++ b/Swiften/Jingle/JingleResponder.cpp @@ -9,7 +9,7 @@  #include <boost/smart_ptr/make_shared.hpp>  #include <Swiften/Jingle/JingleSessionManager.h> -#include <Swiften/Jingle/IncomingJingleSession.h> +#include <Swiften/Jingle/JingleSessionImpl.h>  namespace Swift { @@ -24,12 +24,12 @@ bool JingleResponder::handleSetRequest(const JID& from, const JID&, const std::s  		}  		else {  			sendResponse(from, id, boost::shared_ptr<JinglePayload>()); -			IncomingJingleSession::ref session = boost::make_shared<IncomingJingleSession>(id, payload->getContents()); -			sessionManager->handleIncomingSession(from, session); +			JingleSessionImpl::ref session = boost::make_shared<JingleSessionImpl>(payload->getInitiator(), payload->getSessionID()); +			sessionManager->handleIncomingSession(from, session, payload->getContents());  		}  	}  	else { -		JingleSession::ref session = sessionManager->getSession(from, payload->getSessionID()); +		JingleSessionImpl::ref session = sessionManager->getSession(from, payload->getSessionID());  		if (session) {  			session->handleIncomingAction(payload);  			sendResponse(from, id, boost::shared_ptr<JinglePayload>()); diff --git a/Swiften/Jingle/JingleSession.cpp b/Swiften/Jingle/JingleSession.cpp index d255abd..1366191 100644 --- a/Swiften/Jingle/JingleSession.cpp +++ b/Swiften/Jingle/JingleSession.cpp @@ -10,21 +10,11 @@  namespace Swift { -JingleSession::JingleSession(const std::string& id, const std::vector<JingleContent::ref>& contents) : id(id), contents(contents) { +JingleSession::JingleSession(const JID& initiator, const std::string& id) : initiator(initiator), id(id) {  }  JingleSession::~JingleSession() {  } -void JingleSession::handleIncomingAction(JinglePayload::ref) { -} - -void JingleSession::terminate(JinglePayload::Reason::Type reason) { -	JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionTerminate, id); -	payload->setReason(JinglePayload::Reason(reason)); -	//onAction(payload) -} - -  } diff --git a/Swiften/Jingle/JingleSession.h b/Swiften/Jingle/JingleSession.h index b57701b..fa7da7e 100644 --- a/Swiften/Jingle/JingleSession.h +++ b/Swiften/Jingle/JingleSession.h @@ -7,46 +7,43 @@  #pragma once  #include <boost/shared_ptr.hpp> +#include <string>  #include <Swiften/Base/boost_bsignals.h> -#include <string> +#include <Swiften/JID/JID.h>  #include <Swiften/Elements/JinglePayload.h> -#include <Swiften/Elements/JingleContent.h>  namespace Swift { +	class JingleContentID; +  	class JingleSession { -			friend class JingleResponder;  		public:  			typedef boost::shared_ptr<JingleSession> ref; -			JingleSession(const std::string& id, const std::vector<JingleContent::ref>& contents); +			JingleSession(const JID& initiator, const std::string& id);  			virtual ~JingleSession(); -			std::string getID() const { -				return id; +			const JID& getInitiator() const { +				return initiator;  			} -			template<typename T> -			JingleContent::ref getContentWithDescription() const { -				for (size_t i = 0; i < contents.size(); ++i) { -					if (contents[i]->getDescription<T>()) { -						return contents[i]; -					} -				} -				return JingleContent::ref(); -			} - -			const std::vector<JingleContent::ref> getContents() const { -				return contents; +			std::string getID() const { +				return id;  			} -			void terminate(JinglePayload::Reason::Type reason); +			virtual void terminate(JinglePayload::Reason::Type reason) = 0; +			virtual void accept(JingleTransportPayload::ref = JingleTransportPayload::ref()) = 0; +			virtual void sendTransportInfo(const JingleContentID&, JingleTransportPayload::ref) = 0; +			virtual void acceptTransport(const JingleContentID&, JingleTransportPayload::ref) = 0; +			virtual void rejectTransport(const JingleContentID&, JingleTransportPayload::ref) = 0; -		private: -			void handleIncomingAction(JinglePayload::ref); +		public: +			boost::signal<void ()> onSessionTerminateReceived; +			boost::signal<void (const JingleContentID&, JingleTransportPayload::ref)> onTransportInfoReceived; +			boost::signal<void (const JingleContentID&, JingleTransportPayload::ref)> onTransportReplaceReceived;  		private: +			JID initiator;  			std::string id; -			std::vector<JingleContent::ref> contents;  	};  } diff --git a/Swiften/Jingle/JingleSessionImpl.cpp b/Swiften/Jingle/JingleSessionImpl.cpp new file mode 100644 index 0000000..cbb2b42 --- /dev/null +++ b/Swiften/Jingle/JingleSessionImpl.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Jingle/JingleSessionImpl.h> + +#include <boost/smart_ptr/make_shared.hpp> + +namespace Swift { + +JingleSessionImpl::JingleSessionImpl(const JID& initiator, const std::string& id) : JingleSession(initiator, id) { +} + +void JingleSessionImpl::handleIncomingAction(JinglePayload::ref) { +} + +void JingleSessionImpl::terminate(JinglePayload::Reason::Type reason) { +	JinglePayload::ref payload = boost::make_shared<JinglePayload>(JinglePayload::SessionTerminate, getID()); +	payload->setReason(JinglePayload::Reason(reason)); +	//onAction(payload) +} + +void JingleSessionImpl::acceptTransport(const JingleContentID&, JingleTransportPayload::ref) { + +} + +void JingleSessionImpl::rejectTransport(const JingleContentID&, JingleTransportPayload::ref) { + +} + +void JingleSessionImpl::accept(JingleTransportPayload::ref) { +} + +void JingleSessionImpl::sendTransportInfo(const JingleContentID&, JingleTransportPayload::ref) { + +} + + + +} diff --git a/Swiften/Jingle/JingleSessionImpl.h b/Swiften/Jingle/JingleSessionImpl.h new file mode 100644 index 0000000..a254ead --- /dev/null +++ b/Swiften/Jingle/JingleSessionImpl.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> + +#include <Swiften/Jingle/JingleSession.h> + +namespace Swift { +	class JingleSessionImpl : public JingleSession { +			friend class JingleResponder; +		public: +			typedef boost::shared_ptr<JingleSessionImpl> ref; + +			JingleSessionImpl(const JID& initiator, const std::string& id); + +			virtual void terminate(JinglePayload::Reason::Type reason); +			virtual void accept(JingleTransportPayload::ref); +			virtual void sendTransportInfo(const JingleContentID&, JingleTransportPayload::ref); +			virtual void acceptTransport(const JingleContentID&, JingleTransportPayload::ref); +			virtual void rejectTransport(const JingleContentID&, JingleTransportPayload::ref); + +		private: +			void handleIncomingAction(JinglePayload::ref); +	}; +} diff --git a/Swiften/Jingle/JingleSessionManager.cpp b/Swiften/Jingle/JingleSessionManager.cpp index af512e8..58e90c8 100644 --- a/Swiften/Jingle/JingleSessionManager.cpp +++ b/Swiften/Jingle/JingleSessionManager.cpp @@ -19,9 +19,9 @@ JingleSessionManager::~JingleSessionManager() {  	delete responder;  } -JingleSession::ref JingleSessionManager::getSession(const JID& jid, const std::string& id) const { +JingleSessionImpl::ref JingleSessionManager::getSession(const JID& jid, const std::string& id) const {  	SessionMap::const_iterator i = incomingSessions.find(JIDSession(jid, id)); -	return i != incomingSessions.end() ? i->second : JingleSession::ref(); +	return i != incomingSessions.end() ? i->second : JingleSessionImpl::ref();  }  void JingleSessionManager::addIncomingSessionHandler(IncomingJingleSessionHandler* handler) { @@ -32,10 +32,10 @@ void JingleSessionManager::removeIncomingSessionHandler(IncomingJingleSessionHan  	incomingSessionHandlers.erase(std::remove(incomingSessionHandlers.begin(), incomingSessionHandlers.end(), handler), incomingSessionHandlers.end());  } -void JingleSessionManager::handleIncomingSession(const JID& from, IncomingJingleSession::ref session) { +void JingleSessionManager::handleIncomingSession(const JID& from, JingleSessionImpl::ref session, const std::vector<JingleContentPayload::ref>& contents) {  	incomingSessions.insert(std::make_pair(JIDSession(from, session->getID()), session));  	foreach (IncomingJingleSessionHandler* handler, incomingSessionHandlers) { -		if (handler->handleIncomingJingleSession(session)) { +		if (handler->handleIncomingJingleSession(session, contents)) {  			return;  		}  	} diff --git a/Swiften/Jingle/JingleSessionManager.h b/Swiften/Jingle/JingleSessionManager.h index 3e99656..3b23fb0 100644 --- a/Swiften/Jingle/JingleSessionManager.h +++ b/Swiften/Jingle/JingleSessionManager.h @@ -10,7 +10,7 @@  #include <map>  #include <Swiften/Base/boost_bsignals.h> -#include <Swiften/Jingle/IncomingJingleSession.h> +#include <Swiften/Jingle/JingleSessionImpl.h>  namespace Swift {  	class IQRouter; @@ -23,13 +23,13 @@ namespace Swift {  			JingleSessionManager(IQRouter* router);  			~JingleSessionManager(); -			JingleSession::ref getSession(const JID& jid, const std::string& id) const; +			JingleSessionImpl::ref getSession(const JID& jid, const std::string& id) const;  			void addIncomingSessionHandler(IncomingJingleSessionHandler* handler);  			void removeIncomingSessionHandler(IncomingJingleSessionHandler* handler);  		protected: -			void handleIncomingSession(const JID& from, IncomingJingleSession::ref); +			void handleIncomingSession(const JID& from, JingleSessionImpl::ref, const std::vector<JingleContentPayload::ref>& contents);  		private:  			IQRouter* router; @@ -43,7 +43,7 @@ namespace Swift {  				JID jid;  				std::string session;  			}; -			typedef std::map<JIDSession, JingleSession::ref> SessionMap; +			typedef std::map<JIDSession, JingleSessionImpl::ref> SessionMap;  			SessionMap incomingSessions;  	};  } diff --git a/Swiften/Jingle/SConscript b/Swiften/Jingle/SConscript index a8890b7..6b3cfd3 100644 --- a/Swiften/Jingle/SConscript +++ b/Swiften/Jingle/SConscript @@ -1,11 +1,11 @@  Import("swiften_env")  sources = [ -		"IncomingJingleSession.cpp", +		"JingleSession.cpp", +		"JingleSessionImpl.cpp",	  		"IncomingJingleSessionHandler.cpp",  		"JingleSessionManager.cpp",	  		"JingleResponder.cpp", -		"JingleSession.cpp",  	]  swiften_env.Append(SWIFTEN_OBJECTS = swiften_env.SwiftenObject(sources)) diff --git a/Swiften/Parser/PayloadParsers/IBBParser.cpp b/Swiften/Parser/PayloadParsers/IBBParser.cpp index 308f4ab..8196295 100644 --- a/Swiften/Parser/PayloadParsers/IBBParser.cpp +++ b/Swiften/Parser/PayloadParsers/IBBParser.cpp @@ -64,7 +64,7 @@ void IBBParser::handleEndElement(const std::string& element, const std::string&)  					data.push_back(c);  				}  			} -			getPayloadInternal()->setData(Base64::decode(std::string(&data[0], data.size()))); +			getPayloadInternal()->setData(Base64::decode(std::string(&data[0], data.size())).getDataVector());  		}  	}  } diff --git a/Swiften/Parser/PayloadParsers/UnitTest/IBBParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/IBBParserTest.cpp index b4229f2..2fc3e79 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/IBBParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/IBBParserTest.cpp @@ -32,7 +32,7 @@ class IBBParserTest : public CppUnit::TestFixture {  			IBB::ref ibb = parser.getPayload<IBB>();  			CPPUNIT_ASSERT(ibb->getAction() == IBB::Data); -			CPPUNIT_ASSERT_EQUAL(ByteArray("abcdefgihjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890\x0a"), ibb->getData()); +			CPPUNIT_ASSERT(ByteArray::create("abcdefgihjklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890\x0a") == ibb->getData());  			CPPUNIT_ASSERT_EQUAL(4, ibb->getSequenceNumber());  		}  }; diff --git a/Swiften/QA/StorageTest/FileReadBytestreamTest.cpp b/Swiften/QA/StorageTest/FileReadBytestreamTest.cpp index 925c775..73df0a0 100644 --- a/Swiften/QA/StorageTest/FileReadBytestreamTest.cpp +++ b/Swiften/QA/StorageTest/FileReadBytestreamTest.cpp @@ -7,6 +7,7 @@  #include <cppunit/extensions/HelperMacros.h>  #include <cppunit/extensions/TestFactoryRegistry.h> +#include <Swiften/Base/ByteArray.h>  #include "Swiften/FileTransfer/FileReadBytestream.h"  #include "SwifTools/Application/PlatformApplicationPathProvider.h" @@ -32,16 +33,16 @@ class FileReadBytestreamTest : public CppUnit::TestFixture {  		void testRead() {  			std::auto_ptr<FileReadBytestream> testling(createTestling()); -			ByteArray result = testling->read(10); +			std::vector<unsigned char> result = testling->read(10); -			CPPUNIT_ASSERT_EQUAL(std::string("/*\n * Copy"), result.toString()); +			CPPUNIT_ASSERT(ByteArray::create("/*\n * Copy") == result);  		}  		void testRead_Twice() {  			std::auto_ptr<FileReadBytestream> testling(createTestling());  			testling->read(10); -			ByteArray result = testling->read(10); +			ByteArray result(testling->read(10));  			CPPUNIT_ASSERT_EQUAL(std::string("right (c) "), result.toString());  		} diff --git a/Swiften/SASL/SConscript b/Swiften/SASL/SConscript index 5a0cdef..085e49d 100644 --- a/Swiften/SASL/SConscript +++ b/Swiften/SASL/SConscript @@ -12,6 +12,7 @@ objects = myenv.SwiftenObject([  		"DIGESTMD5ClientAuthenticator.cpp",  	])  swiften_env.Append(SWIFTEN_OBJECTS = [objects]) +  env.Append(UNITTEST_SOURCES = [  			File("UnitTest/PLAINMessageTest.cpp"),  			File("UnitTest/PLAINClientAuthenticatorTest.cpp"), diff --git a/Swiften/SConscript b/Swiften/SConscript index 8961d09..166e2ef 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -212,8 +212,6 @@ if env["SCONS_STAGE"] == "build" :  			File("Elements/UnitTest/FormTest.cpp"),  			File("EventLoop/UnitTest/EventLoopTest.cpp"),  			File("EventLoop/UnitTest/SimpleEventLoopTest.cpp"), -			File("FileTransfer/UnitTest/SOCKS5BytestreamServerSessionTest.cpp"), -			File("FileTransfer/UnitTest/IBBSendSessionTest.cpp"),  #			File("History/UnitTest/SQLiteHistoryManagerTest.cpp"),  			File("JID/UnitTest/JIDTest.cpp"),  			File("LinkLocal/UnitTest/LinkLocalConnectorTest.cpp"), | 
 Swift
 Swift