From 63a8085f02218d2dd2b51acf29280624d6317610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Mon, 1 Nov 2010 21:18:36 +0100 Subject: Added incoming IBB session. diff --git a/Swiften/FileTransfer/FileTransferError.h b/Swiften/FileTransfer/FileTransferError.h index b718927..6a6b454 100644 --- a/Swiften/FileTransfer/FileTransferError.h +++ b/Swiften/FileTransfer/FileTransferError.h @@ -13,6 +13,7 @@ namespace Swift { UnknownError, PeerError, ReadError, + ClosedError, }; FileTransferError(Type type = UnknownError) : type(type) {} diff --git a/Swiften/FileTransfer/FileWriteBytestream.cpp b/Swiften/FileTransfer/FileWriteBytestream.cpp new file mode 100644 index 0000000..b864b6f --- /dev/null +++ b/Swiften/FileTransfer/FileWriteBytestream.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <boost/filesystem/fstream.hpp> +#include <cassert> + +#include "Swiften/FileTransfer/FileWriteBytestream.h" + +namespace Swift { + +FileWriteBytestream::FileWriteBytestream(const boost::filesystem::path& file) : file(file), stream(NULL) { +} + +FileWriteBytestream::~FileWriteBytestream() { + if (stream) { + stream->close(); + stream = NULL; + } +} + +void FileWriteBytestream::write(const ByteArray& data) { + if (!stream) { + stream = new boost::filesystem::ofstream(file, std::ios_base::out|std::ios_base::binary); + } + assert(stream->good()); + stream->write(data.getData(), data.getSize()); +} + +} diff --git a/Swiften/FileTransfer/FileWriteBytestream.h b/Swiften/FileTransfer/FileWriteBytestream.h new file mode 100644 index 0000000..c6f7b39 --- /dev/null +++ b/Swiften/FileTransfer/FileWriteBytestream.h @@ -0,0 +1,26 @@ +/* + * 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/filesystem.hpp> +#include <boost/filesystem/fstream.hpp> + +#include "Swiften/FileTransfer/WriteBytestream.h" + +namespace Swift { + class FileWriteBytestream : public WriteBytestream { + public: + FileWriteBytestream(const boost::filesystem::path& file); + ~FileWriteBytestream(); + + virtual void write(const ByteArray&); + + private: + boost::filesystem::path file; + boost::filesystem::ofstream* stream; + }; +} diff --git a/Swiften/FileTransfer/IBBReceiveSession.cpp b/Swiften/FileTransfer/IBBReceiveSession.cpp new file mode 100644 index 0000000..9eed21d --- /dev/null +++ b/Swiften/FileTransfer/IBBReceiveSession.cpp @@ -0,0 +1,69 @@ +/* + * 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/IBBReceiveSession.h" + +#include <boost/bind.hpp> + +#include "Swiften/Queries/IQRouter.h" +#include "Swiften/FileTransfer/IBBRequest.h" +#include "Swiften/FileTransfer/BytestreamException.h" + +namespace Swift { + +IBBReceiveSession::IBBReceiveSession(const 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) { +} + +IBBReceiveSession::~IBBReceiveSession() { +} + +void IBBReceiveSession::start() { + active = true; +} + +void IBBReceiveSession::stop() { + if (active && router->isAvailable()) { + IBBRequest::create(from, IBB::createIBBClose(id), router)->send(); + } + finish(boost::optional<FileTransferError>()); +} + +void IBBReceiveSession::finish(boost::optional<FileTransferError> error) { + active = false; + onFinished(error); +} + +bool IBBReceiveSession::handleSetRequest(const JID& from, const JID&, const 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 new file mode 100644 index 0000000..b2399b6 --- /dev/null +++ b/Swiften/FileTransfer/IBBReceiveSession.h @@ -0,0 +1,47 @@ +/* + * 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 <boost/optional.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> { + public: + IBBReceiveSession(const String& id, const JID& from, size_t size, WriteBytestream::ref bytestream, IQRouter* router); + ~IBBReceiveSession(); + + void start(); + void stop(); + + boost::signal<void (boost::optional<FileTransferError>)> onFinished; + + private: + bool handleSetRequest(const JID& from, const JID& to, const String& id, IBB::ref payload); + void finish(boost::optional<FileTransferError>); + + private: + String id; + JID from; + size_t size; + WriteBytestream::ref bytestream; + IQRouter* router; + int sequenceNumber; + bool active; + size_t receivedSize; + }; +} diff --git a/Swiften/FileTransfer/IncomingFileTransfer.cpp b/Swiften/FileTransfer/IncomingFileTransfer.cpp new file mode 100644 index 0000000..1962724 --- /dev/null +++ b/Swiften/FileTransfer/IncomingFileTransfer.cpp @@ -0,0 +1,15 @@ +/* + * 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/IncomingFileTransfer.h" + +namespace Swift { + +void IncomingFileTransfer::accept(WriteBytestream::ref) { + +} + +} diff --git a/Swiften/FileTransfer/IncomingFileTransfer.h b/Swiften/FileTransfer/IncomingFileTransfer.h new file mode 100644 index 0000000..d5e7a2f --- /dev/null +++ b/Swiften/FileTransfer/IncomingFileTransfer.h @@ -0,0 +1,21 @@ +/* + * 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/Base/boost_bsignals.h" +#include "Swiften/FileTransfer/WriteBytestream.h" + +namespace Swift { + class IncomingFileTransfer { + public: + typedef boost::shared_ptr<IncomingFileTransfer> ref; + + void accept(WriteBytestream::ref); + }; +} diff --git a/Swiften/FileTransfer/IncomingFileTransferManager.h b/Swiften/FileTransfer/IncomingFileTransferManager.h new file mode 100644 index 0000000..41499e5 --- /dev/null +++ b/Swiften/FileTransfer/IncomingFileTransferManager.h @@ -0,0 +1,18 @@ +/* + * 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/Base/boost_bsignals.h" + +namespace Swift { + class IncomingFileTransferManager { + public: + boost::signal<void (IncomingFileTransfer::ref)> onIncomingFileTransfer; + }; +} diff --git a/Swiften/FileTransfer/SConscript b/Swiften/FileTransfer/SConscript index f42dd88..d36e029 100644 --- a/Swiften/FileTransfer/SConscript +++ b/Swiften/FileTransfer/SConscript @@ -2,12 +2,16 @@ Import("swiften_env") sources = [ "OutgoingFileTransfer.cpp", + "IncomingFileTransfer.cpp", "ReadBytestream.cpp", + "WriteBytestream.cpp", "FileReadBytestream.cpp", + "FileWriteBytestream.cpp", "SOCKS5BytestreamServer.cpp", "SOCKS5BytestreamServerSession.cpp", "SOCKS5BytestreamRegistry.cpp", "IBBSendSession.cpp", + "IBBReceiveSession.cpp", ] swiften_env.Append(SWIFTEN_OBJECTS = swiften_env.StaticObject(sources)) diff --git a/Swiften/FileTransfer/WriteBytestream.cpp b/Swiften/FileTransfer/WriteBytestream.cpp new file mode 100644 index 0000000..f1a5afc --- /dev/null +++ b/Swiften/FileTransfer/WriteBytestream.cpp @@ -0,0 +1,14 @@ +/* + * 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/WriteBytestream.h" + +namespace Swift { + +WriteBytestream::~WriteBytestream() { +} + +} diff --git a/Swiften/FileTransfer/WriteBytestream.h b/Swiften/FileTransfer/WriteBytestream.h new file mode 100644 index 0000000..1dc791c --- /dev/null +++ b/Swiften/FileTransfer/WriteBytestream.h @@ -0,0 +1,22 @@ +/* + * 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/Base/ByteArray.h" + +namespace Swift { + class WriteBytestream { + public: + typedef boost::shared_ptr<WriteBytestream> ref; + + virtual ~WriteBytestream(); + + virtual void write(const ByteArray&) = 0; + }; +} -- cgit v0.10.2-6-g49f6