diff options
Diffstat (limited to 'Swiften/FileTransfer/IBBReceiveSession.cpp')
-rw-r--r-- | Swiften/FileTransfer/IBBReceiveSession.cpp | 122 |
1 files changed, 84 insertions, 38 deletions
diff --git a/Swiften/FileTransfer/IBBReceiveSession.cpp b/Swiften/FileTransfer/IBBReceiveSession.cpp index 5c90757..1a2bb3a 100644 --- a/Swiften/FileTransfer/IBBReceiveSession.cpp +++ b/Swiften/FileTransfer/IBBReceiveSession.cpp @@ -4,31 +4,107 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/FileTransfer/IBBReceiveSession.h" +#include <Swiften/FileTransfer/IBBReceiveSession.h> #include <boost/bind.hpp> -#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> + +#include <cassert> 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) { + SWIFT_LOG(debug) << "IBB open received" << std::endl; + sendResponse(from, id, IBB::ref()); + } + else if (ibb->getAction() == IBB::Close) { + SWIFT_LOG(debug) << "IBB close received" << std::endl; + sendResponse(from, id, IBB::ref()); + session->finish(FileTransferError(FileTransferError::ClosedError)); + } + return true; + } + SWIFT_LOG(debug) << "wrong from/sessionID: " << from << " == " << session->from << " / " <<ibb->getStreamID() << " == " << session->id << std::endl; + return false; + } + + private: + IBBReceiveSession* session; + int sequenceNumber; + size_t receivedSize; +}; + + +IBBReceiveSession::IBBReceiveSession( + const std::string& id, + const JID& from, + const JID& to, + size_t size, + IQRouter* router) : + id(id), + from(from), + to(to), + size(size), + router(router), + active(false) { + assert(!id.empty()); + assert(from.isValid()); + responder = new IBBResponder(this, router); } IBBReceiveSession::~IBBReceiveSession() { + if (active) { + SWIFT_LOG(warning) << "Session still active" << std::endl; + } + delete responder; } void IBBReceiveSession::start() { + SWIFT_LOG(debug) << "receive session started" << std::endl; active = true; + responder->start(); } void IBBReceiveSession::stop() { - if (active && router->isAvailable()) { - IBBRequest::create(from, IBB::createIBBClose(id), router)->send(); + SWIFT_LOG(debug) << "receive session stopped" << std::endl; + responder->stop(); + if (active) { + if (router->isAvailable()) { + IBBRequest::create(to, from, IBB::createIBBClose(id), router)->send(); + } + finish(boost::optional<FileTransferError>()); } - finish(boost::optional<FileTransferError>()); } void IBBReceiveSession::finish(boost::optional<FileTransferError> error) { @@ -36,34 +112,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; -} - } |