summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swiften/Elements/JingleContent.h89
-rw-r--r--Swiften/Elements/JingleDescription.h18
-rw-r--r--Swiften/Elements/JingleFileTransferDescription.h31
-rw-r--r--Swiften/Elements/JingleIBBTransport.h49
-rw-r--r--Swiften/Elements/JinglePayload.h125
-rw-r--r--Swiften/Elements/JingleS5BTransport.h26
-rw-r--r--Swiften/Elements/JingleTransport.h14
-rw-r--r--Swiften/Elements/StreamInitiation.h15
-rw-r--r--Swiften/Elements/StreamInitiationFileInfo.h19
-rw-r--r--Swiften/Examples/SendFile/.gitignore1
-rw-r--r--Swiften/Examples/SendFile/ReceiveFile.cpp116
-rw-r--r--Swiften/Examples/SendFile/SConscript4
-rw-r--r--Swiften/FileTransfer/IncomingFileTransfer.cpp10
-rw-r--r--Swiften/FileTransfer/IncomingFileTransfer.h4
-rw-r--r--Swiften/FileTransfer/IncomingFileTransferManager.cpp46
-rw-r--r--Swiften/FileTransfer/IncomingFileTransferManager.h19
-rw-r--r--Swiften/FileTransfer/IncomingJingleFileTransfer.cpp19
-rw-r--r--Swiften/FileTransfer/IncomingJingleFileTransfer.h27
-rw-r--r--Swiften/FileTransfer/OutgoingFileTransfer.cpp2
-rw-r--r--Swiften/FileTransfer/SConscript2
-rw-r--r--Swiften/Jingle/IncomingJingleSession.cpp15
-rw-r--r--Swiften/Jingle/IncomingJingleSession.h20
-rw-r--r--Swiften/Jingle/IncomingJingleSessionHandler.cpp14
-rw-r--r--Swiften/Jingle/IncomingJingleSessionHandler.h18
-rw-r--r--Swiften/Jingle/JingleResponder.cpp45
-rw-r--r--Swiften/Jingle/JingleResponder.h26
-rw-r--r--Swiften/Jingle/JingleSession.cpp30
-rw-r--r--Swiften/Jingle/JingleSession.h53
-rw-r--r--Swiften/Jingle/JingleSessionManager.cpp45
-rw-r--r--Swiften/Jingle/JingleSessionManager.h49
-rw-r--r--Swiften/Jingle/SConscript11
-rw-r--r--Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp2
-rw-r--r--Swiften/Parser/PayloadParsers/StreamInitiationParser.h2
-rw-r--r--Swiften/SConscript1
-rw-r--r--Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp2
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp2
36 files changed, 950 insertions, 21 deletions
diff --git a/Swiften/Elements/JingleContent.h b/Swiften/Elements/JingleContent.h
new file mode 100644
index 0000000..bf419aa
--- /dev/null
+++ b/Swiften/Elements/JingleContent.h
@@ -0,0 +1,89 @@
+/*
+ * 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 <boost/optional.hpp>
+
+#include <Swiften/Base/String.h>
+#include <Swiften/JID/JID.h>
+#include <Swiften/Elements/Payload.h>
+#include <Swiften/Elements/JingleDescription.h>
+#include <Swiften/Elements/JingleTransport.h>
+#include <Swiften/Base/foreach.h>
+
+namespace Swift {
+ class JingleContent : public Payload {
+ public:
+ typedef boost::shared_ptr<JingleContent> ref;
+
+ enum Creator {
+ InitiatorCreator,
+ ResponderCreator,
+ };
+
+ /*enum Senders {
+ NoSenders,
+ InitiatorSender,
+ ResponderSender,
+ BothSenders,
+ };*/
+
+ void setCreator(Creator creator) {
+ this->creator = creator;
+ }
+
+ void setName(const String& name) {
+ this->name = name;
+ }
+
+ const std::vector<JingleDescription::ref>& getDescriptions() const {
+ return descriptions;
+ }
+
+ void addDescription(JingleDescription::ref description) {
+ descriptions.push_back(description);
+ }
+
+ const std::vector<JingleTransport::ref>& getTransports() const {
+ return transports;
+ }
+
+ void addTransport(JingleTransport::ref transport) {
+ transports.push_back(transport);
+ }
+
+ template<typename T>
+ boost::shared_ptr<T> getDescription() const {
+ foreach (JingleDescription::ref i, descriptions) {
+ boost::shared_ptr<T> result(boost::dynamic_pointer_cast<T>(i));
+ if (result) {
+ return result;
+ }
+ }
+ return boost::shared_ptr<T>();
+ }
+
+ template<typename T>
+ boost::shared_ptr<T> getTransport() const {
+ foreach (JingleTransport::ref i, transports) {
+ boost::shared_ptr<T> result(boost::dynamic_pointer_cast<T>(i));
+ if (result) {
+ return result;
+ }
+ }
+ return boost::shared_ptr<T>();
+ }
+
+ private:
+ Creator creator;
+ String name;
+ //Senders senders;
+ std::vector<JingleDescription::ref> descriptions;
+ std::vector<JingleTransport::ref> transports;
+ };
+}
diff --git a/Swiften/Elements/JingleDescription.h b/Swiften/Elements/JingleDescription.h
new file mode 100644
index 0000000..775c0f7
--- /dev/null
+++ b/Swiften/Elements/JingleDescription.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
+
+#include <boost/shared_ptr.hpp>
+
+#include <Swiften/Elements/Payload.h>
+
+namespace Swift {
+ class JingleDescription : public Payload {
+ public:
+ typedef boost::shared_ptr<JingleDescription> ref;
+ };
+}
diff --git a/Swiften/Elements/JingleFileTransferDescription.h b/Swiften/Elements/JingleFileTransferDescription.h
new file mode 100644
index 0000000..19644bd
--- /dev/null
+++ b/Swiften/Elements/JingleFileTransferDescription.h
@@ -0,0 +1,31 @@
+/*
+ * 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 <boost/optional.hpp>
+
+#include <Swiften/Elements/JingleDescription.h>
+#include <Swiften/Elements/StreamInitiationFileInfo.h>
+
+namespace Swift {
+ class JingleFileTransferDescription : public JingleDescription {
+ public:
+ typedef boost::shared_ptr<JingleFileTransferDescription> ref;
+
+ void setOffer(const StreamInitiationFileInfo& offer) {
+ this->offer = offer;
+ }
+
+ const boost::optional<StreamInitiationFileInfo>& getOffer() const {
+ return offer;
+ }
+
+ private:
+ boost::optional<StreamInitiationFileInfo> offer;
+ };
+}
diff --git a/Swiften/Elements/JingleIBBTransport.h b/Swiften/Elements/JingleIBBTransport.h
new file mode 100644
index 0000000..ca3ecc8
--- /dev/null
+++ b/Swiften/Elements/JingleIBBTransport.h
@@ -0,0 +1,49 @@
+/*
+ * 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/String.h>
+#include <Swiften/Elements/JingleTransport.h>
+
+namespace Swift {
+ class JingleIBBTransport : public JingleTransport {
+ public:
+ enum StanzaType {
+ IQStanza,
+ MessageStanza,
+ };
+
+ void setStanzaType(StanzaType stanzaType) {
+ this->stanzaType = stanzaType;
+ }
+
+ StanzaType getStanzaType() const {
+ return stanzaType;
+ }
+
+ void setSessionID(const String& id) {
+ sessionID = id;
+ }
+
+ const String& getSessionID() const {
+ return sessionID;
+ }
+
+ int getBlockSize() const {
+ return blockSize;
+ }
+
+ void setBlockSize(int blockSize) {
+ this->blockSize = blockSize;
+ }
+
+ private:
+ String sessionID;
+ int blockSize;
+ StanzaType stanzaType;
+ };
+}
diff --git a/Swiften/Elements/JinglePayload.h b/Swiften/Elements/JinglePayload.h
new file mode 100644
index 0000000..66b6d43
--- /dev/null
+++ b/Swiften/Elements/JinglePayload.h
@@ -0,0 +1,125 @@
+/*
+ * 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 <boost/optional.hpp>
+
+#include <Swiften/Base/String.h>
+#include <Swiften/JID/JID.h>
+#include <Swiften/Elements/Payload.h>
+#include <Swiften/Elements/JingleContent.h>
+
+
+namespace Swift {
+ class JinglePayload : public Payload {
+ public:
+ typedef boost::shared_ptr<JinglePayload> ref;
+ struct Reason {
+ enum Type {
+ AlternativeSession,
+ Busy,
+ Cancel,
+ ConnectivityError,
+ Decline,
+ Expired,
+ FailedApplication,
+ FailedTransport,
+ GeneralError,
+ Gone,
+ IncompatibleParameters,
+ MediaError,
+ SecurityError,
+ Success,
+ Timeout,
+ UnsupportedApplications,
+ UnsupportedTransports
+ };
+
+ Reason(Type type, const String& text = "") : type(type), text(text) {}
+ Type type;
+ String text;
+ };
+
+ enum Action {
+ ContentAccept,
+ ContentAdd,
+ ContentModify,
+ ContentReject,
+ ContentRemove,
+ DescriptionInfo,
+ SecurityInfo,
+ SessionAccept,
+ SessionInfo,
+ SessionInitiate,
+ SessionTerminate,
+ TransportAccept,
+ TransportInfo,
+ TransportReject,
+ TransportReplace
+ };
+
+ JinglePayload(Action action, const String& sessionID) : action(action), sessionID(sessionID) {
+ }
+
+ void setAction(Action action) {
+ this->action = action;
+ }
+
+ Action getAction() const {
+ return action;
+ }
+
+ void setInitiator(const JID& initiator) {
+ this->initiator = initiator;
+ }
+
+ const JID& getInitiator() const {
+ return initiator;
+ }
+
+ void setResponder(const JID& responder) {
+ this->responder = responder;
+ }
+
+ const JID& getResponder() const {
+ return responder;
+ }
+
+ void setSessionID(const String& id) {
+ sessionID = id;
+ }
+
+ const String& getSessionID() const {
+ return sessionID;
+ }
+
+ void addContent(JingleContent::ref content) {
+ this->contents.push_back(content);
+ }
+
+ const std::vector<JingleContent::ref> getContents() const {
+ return contents;
+ }
+
+ void setReason(const Reason& reason) {
+ this->reason = reason;
+ }
+
+ const boost::optional<Reason>& getReason() const {
+ return reason;
+ }
+
+ private:
+ Action action;
+ JID initiator;
+ JID responder;
+ String sessionID;
+ std::vector<JingleContent::ref> contents;
+ boost::optional<Reason> reason;
+ };
+}
diff --git a/Swiften/Elements/JingleS5BTransport.h b/Swiften/Elements/JingleS5BTransport.h
new file mode 100644
index 0000000..4522417
--- /dev/null
+++ b/Swiften/Elements/JingleS5BTransport.h
@@ -0,0 +1,26 @@
+/*
+ * 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/Elements/JingleTransport.h>
+#include <Swiften/Elements/Bytestreams.h>
+
+namespace Swift {
+ class JingleS5BTransport : public JingleTransport {
+ public:
+ const Bytestreams& getInfo() const {
+ return info;
+ }
+
+ void setInfo(const Bytestreams& info) {
+ this->info = info;
+ }
+
+ private:
+ Bytestreams info;
+ };
+}
diff --git a/Swiften/Elements/JingleTransport.h b/Swiften/Elements/JingleTransport.h
new file mode 100644
index 0000000..ecd2a34
--- /dev/null
+++ b/Swiften/Elements/JingleTransport.h
@@ -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.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/Payload.h>
+
+namespace Swift {
+ class JingleTransport : public Payload {
+ };
+}
diff --git a/Swiften/Elements/StreamInitiation.h b/Swiften/Elements/StreamInitiation.h
index 55b6b87..16dfd4d 100644
--- a/Swiften/Elements/StreamInitiation.h
+++ b/Swiften/Elements/StreamInitiation.h
@@ -12,20 +12,13 @@
#include "Swiften/Base/String.h"
#include "Swiften/Elements/Payload.h"
+#include <Swiften/Elements/StreamInitiationFileInfo.h>
namespace Swift {
class StreamInitiation : public Payload {
public:
typedef boost::shared_ptr<StreamInitiation> ref;
- struct FileInfo {
- FileInfo(const String& name = "", const String& description = "", int size = -1) : name(name), description(description), size(size) {}
-
- String name;
- String description;
- int size;
- };
-
StreamInitiation() : isFileTransfer(true) {}
const String& getID() const {
@@ -36,11 +29,11 @@ namespace Swift {
this->id = id;
}
- const boost::optional<FileInfo>& getFileInfo() const {
+ const boost::optional<StreamInitiationFileInfo>& getFileInfo() const {
return fileInfo;
}
- void setFileInfo(const FileInfo& info) {
+ void setFileInfo(const StreamInitiationFileInfo& info) {
fileInfo = info;
}
@@ -71,7 +64,7 @@ namespace Swift {
private:
bool isFileTransfer;
String id;
- boost::optional<FileInfo> fileInfo;
+ boost::optional<StreamInitiationFileInfo> fileInfo;
std::vector<String> providedMethods;
String requestedMethod;
};
diff --git a/Swiften/Elements/StreamInitiationFileInfo.h b/Swiften/Elements/StreamInitiationFileInfo.h
new file mode 100644
index 0000000..15b5a66
--- /dev/null
+++ b/Swiften/Elements/StreamInitiationFileInfo.h
@@ -0,0 +1,19 @@
+/*
+ * 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/String.h>
+
+namespace Swift {
+ struct StreamInitiationFileInfo {
+ StreamInitiationFileInfo(const String& name = "", const String& description = "", int size = -1) : name(name), description(description), size(size) {}
+
+ String name;
+ String description;
+ int size;
+ };
+}
diff --git a/Swiften/Examples/SendFile/.gitignore b/Swiften/Examples/SendFile/.gitignore
index f8b7625..b40e042 100644
--- a/Swiften/Examples/SendFile/.gitignore
+++ b/Swiften/Examples/SendFile/.gitignore
@@ -1 +1,2 @@
SendFile
+ReceiveFile
diff --git a/Swiften/Examples/SendFile/ReceiveFile.cpp b/Swiften/Examples/SendFile/ReceiveFile.cpp
new file mode 100644
index 0000000..a6386cd
--- /dev/null
+++ b/Swiften/Examples/SendFile/ReceiveFile.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <boost/bind.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+
+#include <Swiften/Client/Client.h>
+#include <Swiften/Network/BoostNetworkFactories.h>
+#include <Swiften/EventLoop/SimpleEventLoop.h>
+#include <Swiften/Client/ClientXMLTracer.h>
+#include <Swiften/FileTransfer/IncomingFileTransferManager.h>
+#include <Swiften/FileTransfer/FileWriteBytestream.h>
+#include <Swiften/Jingle/JingleSessionManager.h>
+
+using namespace Swift;
+
+SimpleEventLoop eventLoop;
+BoostNetworkFactories networkFactories(&eventLoop);
+
+int exitCode = 2;
+
+class FileReceiver {
+ public:
+ FileReceiver(const JID& jid, const String& password) : jid(jid), password(password), jingleSessionManager(NULL), incomingFileTransferManager(NULL) {
+ client = new Swift::Client(&eventLoop, &networkFactories, jid, password);
+ client->onConnected.connect(boost::bind(&FileReceiver::handleConnected, this));
+ client->onDisconnected.connect(boost::bind(&FileReceiver::handleDisconnected, this, _1));
+ //tracer = new ClientXMLTracer(client);
+ }
+
+ ~FileReceiver() {
+ delete incomingFileTransferManager;
+ delete jingleSessionManager;
+ //delete tracer;
+ client->onDisconnected.disconnect(boost::bind(&FileReceiver::handleDisconnected, this, _1));
+ client->onConnected.disconnect(boost::bind(&FileReceiver::handleConnected, this));
+ delete client;
+ }
+
+ void start() {
+ client->connect();
+ }
+
+ void stop() {
+ foreach(const IncomingFileTransfer::ref transfer, incomingFileTransfers) {
+ //transfer->stop();
+ }
+ client->disconnect();
+ }
+
+ private:
+ void handleConnected() {
+ client->sendPresence(Presence::create());
+ jingleSessionManager = new JingleSessionManager(client->getIQRouter());
+ incomingFileTransferManager = new IncomingFileTransferManager(jingleSessionManager, client->getIQRouter());
+ incomingFileTransferManager->onIncomingFileTransfer.connect(boost::bind(&FileReceiver::handleIncomingFileTransfer, this, _1));
+ }
+
+ void handleIncomingFileTransfer(IncomingFileTransfer::ref transfer) {
+ incomingFileTransfers.push_back(transfer);
+ transfer->accept(boost::make_shared<FileWriteBytestream>("out"));
+ //transfer->onFinished.connect(boost::bind(&FileReceiver::handleFileTransferFinished, this, _1));
+ //transfer->start();
+ }
+
+ void handleDisconnected(const boost::optional<ClientError>&) {
+ std::cerr << "Error!" << std::endl;
+ exit(-1);
+ }
+
+ /*
+ void handleFileTransferFinished(const boost::optional<FileTransferError>& error) {
+ std::cout << "File transfer finished" << std::endl;
+ if (error) {
+ exit(-1);
+ }
+ else {
+ exit(0);
+ }
+ }*/
+
+ void exit(int code) {
+ exitCode = code;
+ stop();
+ eventLoop.stop();
+ }
+
+ private:
+ JID jid;
+ String password;
+ Client* client;
+ ClientXMLTracer* tracer;
+ JingleSessionManager* jingleSessionManager;
+ IncomingFileTransferManager* incomingFileTransferManager;
+ std::vector<IncomingFileTransfer::ref> incomingFileTransfers;
+};
+
+
+int main(int argc, char* argv[]) {
+ if (argc != 3) {
+ std::cerr << "Usage: " << argv[0] << " <jid> <password>" << std::endl;
+ return -1;
+ }
+
+ JID jid(argv[1]);
+ FileReceiver fileReceiver(jid, String(argv[2]));
+ fileReceiver.start();
+
+ eventLoop.run();
+
+ return exitCode;
+}
diff --git a/Swiften/Examples/SendFile/SConscript b/Swiften/Examples/SendFile/SConscript
index 50cbe40..6986f22 100644
--- a/Swiften/Examples/SendFile/SConscript
+++ b/Swiften/Examples/SendFile/SConscript
@@ -10,4 +10,6 @@ myenv.MergeFlags(myenv.get("SQLITE_FLAGS", {}))
myenv.MergeFlags(myenv.get("LIBXML_FLAGS", ""))
myenv.MergeFlags(myenv.get("EXPAT_FLAGS", ""))
myenv.MergeFlags(myenv["PLATFORM_FLAGS"])
-tester = myenv.Program("SendFile", ["SendFile.cpp"])
+
+myenv.Program("SendFile", ["SendFile.cpp"])
+myenv.Program("ReceiveFile", ["ReceiveFile.cpp"])
diff --git a/Swiften/FileTransfer/IncomingFileTransfer.cpp b/Swiften/FileTransfer/IncomingFileTransfer.cpp
index 1962724..238ccce 100644
--- a/Swiften/FileTransfer/IncomingFileTransfer.cpp
+++ b/Swiften/FileTransfer/IncomingFileTransfer.cpp
@@ -8,8 +8,16 @@
namespace Swift {
-void IncomingFileTransfer::accept(WriteBytestream::ref) {
+IncomingFileTransfer::~IncomingFileTransfer() {
}
+/*void IncomingFileTransfer::accept(WriteBytestream::ref) {
+
+}
+
+void IncomingFileTransfer::stop() {
+
+}*/
+
}
diff --git a/Swiften/FileTransfer/IncomingFileTransfer.h b/Swiften/FileTransfer/IncomingFileTransfer.h
index d5e7a2f..4286ef0 100644
--- a/Swiften/FileTransfer/IncomingFileTransfer.h
+++ b/Swiften/FileTransfer/IncomingFileTransfer.h
@@ -16,6 +16,8 @@ namespace Swift {
public:
typedef boost::shared_ptr<IncomingFileTransfer> ref;
- void accept(WriteBytestream::ref);
+ virtual ~IncomingFileTransfer();
+
+ virtual void accept(WriteBytestream::ref) = 0;
};
}
diff --git a/Swiften/FileTransfer/IncomingFileTransferManager.cpp b/Swiften/FileTransfer/IncomingFileTransferManager.cpp
new file mode 100644
index 0000000..5535840
--- /dev/null
+++ b/Swiften/FileTransfer/IncomingFileTransferManager.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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/IncomingFileTransferManager.h>
+
+#include <boost/smart_ptr/make_shared.hpp>
+
+#include <Swiften/Elements/JingleDescription.h>
+#include <Swiften/Elements/JingleFileTransferDescription.h>
+#include <Swiften/Elements/JingleIBBTransport.h>
+#include <Swiften/Jingle/JingleSessionManager.h>
+#include <Swiften/FileTransfer/IncomingJingleFileTransfer.h>
+
+namespace Swift {
+
+IncomingFileTransferManager::IncomingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router) : jingleSessionManager(jingleSessionManager), router(router) {
+ jingleSessionManager->addIncomingSessionHandler(this);
+}
+
+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);
+ onIncomingFileTransfer(transfer);
+ }
+ else {
+ session->terminate(JinglePayload::Reason::UnsupportedTransports);
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+
+}
diff --git a/Swiften/FileTransfer/IncomingFileTransferManager.h b/Swiften/FileTransfer/IncomingFileTransferManager.h
index 41499e5..a54b5cd 100644
--- a/Swiften/FileTransfer/IncomingFileTransferManager.h
+++ b/Swiften/FileTransfer/IncomingFileTransferManager.h
@@ -8,11 +8,26 @@
#include <boost/shared_ptr.hpp>
-#include "Swiften/Base/boost_bsignals.h"
+#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/FileTransfer/IncomingFileTransfer.h>
+#include <Swiften/Jingle/IncomingJingleSessionHandler.h>
namespace Swift {
- class IncomingFileTransferManager {
+ class IQRouter;
+ class JingleSessionManager;
+
+ class IncomingFileTransferManager : public IncomingJingleSessionHandler {
public:
+ IncomingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router);
+ ~IncomingFileTransferManager();
+
boost::signal<void (IncomingFileTransfer::ref)> onIncomingFileTransfer;
+
+ private:
+ bool handleIncomingJingleSession(IncomingJingleSession::ref session);
+
+ private:
+ JingleSessionManager* jingleSessionManager;
+ IQRouter* router;
};
}
diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp
new file mode 100644
index 0000000..cb2f65c
--- /dev/null
+++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp
@@ -0,0 +1,19 @@
+/*
+ * 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/IncomingJingleFileTransfer.h>
+
+namespace Swift {
+
+IncomingJingleFileTransfer::IncomingJingleFileTransfer(IncomingJingleSession::ref session) : session(session) {
+
+}
+
+void IncomingJingleFileTransfer::accept(WriteBytestream::ref stream) {
+ this->stream = stream;
+}
+
+}
diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.h b/Swiften/FileTransfer/IncomingJingleFileTransfer.h
new file mode 100644
index 0000000..d69449e
--- /dev/null
+++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.h
@@ -0,0 +1,27 @@
+/*
+ * 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/Jingle/IncomingJingleSession.h>
+#include <Swiften/FileTransfer/IncomingFileTransfer.h>
+
+namespace Swift {
+ class IncomingJingleFileTransfer : public IncomingFileTransfer {
+ public:
+ typedef boost::shared_ptr<IncomingJingleFileTransfer> ref;
+
+ IncomingJingleFileTransfer(IncomingJingleSession::ref session);
+
+ virtual void accept(WriteBytestream::ref);
+
+ private:
+ IncomingJingleSession::ref session;
+ WriteBytestream::ref stream;
+ };
+}
diff --git a/Swiften/FileTransfer/OutgoingFileTransfer.cpp b/Swiften/FileTransfer/OutgoingFileTransfer.cpp
index 4fa8d94..8e6f839 100644
--- a/Swiften/FileTransfer/OutgoingFileTransfer.cpp
+++ b/Swiften/FileTransfer/OutgoingFileTransfer.cpp
@@ -21,7 +21,7 @@ OutgoingFileTransfer::OutgoingFileTransfer(const String& id, const JID& from, co
void OutgoingFileTransfer::start() {
StreamInitiation::ref streamInitiation(new StreamInitiation());
streamInitiation->setID(id);
- streamInitiation->setFileInfo(StreamInitiation::FileInfo(name, description, size));
+ 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);
diff --git a/Swiften/FileTransfer/SConscript b/Swiften/FileTransfer/SConscript
index d36e029..9f3234f 100644
--- a/Swiften/FileTransfer/SConscript
+++ b/Swiften/FileTransfer/SConscript
@@ -3,6 +3,8 @@ Import("swiften_env")
sources = [
"OutgoingFileTransfer.cpp",
"IncomingFileTransfer.cpp",
+ "IncomingJingleFileTransfer.cpp",
+ "IncomingFileTransferManager.cpp",
"ReadBytestream.cpp",
"WriteBytestream.cpp",
"FileReadBytestream.cpp",
diff --git a/Swiften/Jingle/IncomingJingleSession.cpp b/Swiften/Jingle/IncomingJingleSession.cpp
new file mode 100644
index 0000000..29155b8
--- /dev/null
+++ b/Swiften/Jingle/IncomingJingleSession.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/Jingle/IncomingJingleSession.h>
+
+namespace Swift {
+
+IncomingJingleSession::IncomingJingleSession(const String& id, const std::vector<JingleContent::ref>& contents) : JingleSession(id, contents) {
+
+}
+
+}
diff --git a/Swiften/Jingle/IncomingJingleSession.h b/Swiften/Jingle/IncomingJingleSession.h
new file mode 100644
index 0000000..222100f
--- /dev/null
+++ b/Swiften/Jingle/IncomingJingleSession.h
@@ -0,0 +1,20 @@
+/*
+ * 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 String& id, const std::vector<JingleContent::ref>& contents);
+
+ typedef boost::shared_ptr<IncomingJingleSession> ref;
+ };
+}
diff --git a/Swiften/Jingle/IncomingJingleSessionHandler.cpp b/Swiften/Jingle/IncomingJingleSessionHandler.cpp
new file mode 100644
index 0000000..d38118c
--- /dev/null
+++ b/Swiften/Jingle/IncomingJingleSessionHandler.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/Jingle/IncomingJingleSessionHandler.h>
+
+namespace Swift {
+
+IncomingJingleSessionHandler::~IncomingJingleSessionHandler() {
+}
+
+}
diff --git a/Swiften/Jingle/IncomingJingleSessionHandler.h b/Swiften/Jingle/IncomingJingleSessionHandler.h
new file mode 100644
index 0000000..5bf9237
--- /dev/null
+++ b/Swiften/Jingle/IncomingJingleSessionHandler.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
+
+#include <Swiften/Jingle/IncomingJingleSession.h>
+
+namespace Swift {
+ class IncomingJingleSessionHandler {
+ public:
+ virtual ~IncomingJingleSessionHandler();
+
+ virtual bool handleIncomingJingleSession(IncomingJingleSession::ref) = 0;
+ };
+}
diff --git a/Swiften/Jingle/JingleResponder.cpp b/Swiften/Jingle/JingleResponder.cpp
new file mode 100644
index 0000000..3dfc327
--- /dev/null
+++ b/Swiften/Jingle/JingleResponder.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Jingle/JingleResponder.h>
+
+#include <boost/smart_ptr/make_shared.hpp>
+
+#include <Swiften/Jingle/JingleSessionManager.h>
+#include <Swiften/Jingle/IncomingJingleSession.h>
+
+namespace Swift {
+
+JingleResponder::JingleResponder(JingleSessionManager* sessionManager, IQRouter* router) : SetResponder<JinglePayload>(router), sessionManager(sessionManager) {
+}
+
+bool JingleResponder::handleSetRequest(const JID& from, const JID&, const String& id, boost::shared_ptr<JinglePayload> payload) {
+ if (payload->getAction() == JinglePayload::SessionInitiate) {
+ if (sessionManager->getSession(from, payload->getSessionID())) {
+ // TODO: Add tie-break error
+ sendError(from, id, ErrorPayload::Conflict, ErrorPayload::Cancel);
+ }
+ else {
+ sendResponse(from, id, boost::shared_ptr<JinglePayload>());
+ IncomingJingleSession::ref session = boost::make_shared<IncomingJingleSession>(id, payload->getContents());
+ sessionManager->handleIncomingSession(from, session);
+ }
+ }
+ else {
+ JingleSession::ref session = sessionManager->getSession(from, payload->getSessionID());
+ if (session) {
+ session->handleIncomingAction(payload);
+ sendResponse(from, id, boost::shared_ptr<JinglePayload>());
+ }
+ else {
+ // TODO: Add jingle-specific error
+ sendError(from, id, ErrorPayload::ItemNotFound, ErrorPayload::Cancel);
+ }
+ }
+ return true;
+}
+
+}
diff --git a/Swiften/Jingle/JingleResponder.h b/Swiften/Jingle/JingleResponder.h
new file mode 100644
index 0000000..47dc90a
--- /dev/null
+++ b/Swiften/Jingle/JingleResponder.h
@@ -0,0 +1,26 @@
+/*
+ * 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/Queries/SetResponder.h>
+#include <Swiften/Elements/JinglePayload.h>
+
+namespace Swift {
+ class IQRouter;
+ class JingleSessionManager;
+
+ class JingleResponder : public SetResponder<JinglePayload> {
+ public:
+ JingleResponder(JingleSessionManager* sessionManager, IQRouter* router);
+
+ private:
+ virtual bool handleSetRequest(const JID& from, const JID& to, const String& id, boost::shared_ptr<JinglePayload> payload);
+
+ private:
+ JingleSessionManager* sessionManager;
+ };
+}
diff --git a/Swiften/Jingle/JingleSession.cpp b/Swiften/Jingle/JingleSession.cpp
new file mode 100644
index 0000000..3dbb12a
--- /dev/null
+++ b/Swiften/Jingle/JingleSession.cpp
@@ -0,0 +1,30 @@
+/*
+ * 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/JingleSession.h>
+
+#include <boost/smart_ptr/make_shared.hpp>
+
+namespace Swift {
+
+JingleSession::JingleSession(const String& id, const std::vector<JingleContent::ref>& contents) : id(id), contents(contents) {
+
+}
+
+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
new file mode 100644
index 0000000..7ed86c2
--- /dev/null
+++ b/Swiften/Jingle/JingleSession.h
@@ -0,0 +1,53 @@
+/*
+ * 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>
+#include <Swiften/Base/String.h>
+#include <Swiften/Elements/JinglePayload.h>
+#include <Swiften/Elements/JingleContent.h>
+#include <Swiften/Base/foreach.h>
+
+namespace Swift {
+ class JingleSession {
+ friend class JingleResponder;
+ public:
+ typedef boost::shared_ptr<JingleSession> ref;
+
+ JingleSession(const String& id, const std::vector<JingleContent::ref>& contents);
+ virtual ~JingleSession();
+
+ String getID() const {
+ return id;
+ }
+
+ template<typename T>
+ JingleContent::ref getContentWithDescription() const {
+ foreach (JingleContent::ref content, contents) {
+ if (content->getDescription<T>()) {
+ return content;
+ }
+ }
+ return JingleContent::ref();
+ }
+
+ const std::vector<JingleContent::ref> getContents() const {
+ return contents;
+ }
+
+ void terminate(JinglePayload::Reason::Type reason);
+
+ private:
+ void handleIncomingAction(JinglePayload::ref);
+
+ private:
+ String id;
+ std::vector<JingleContent::ref> contents;
+ };
+}
diff --git a/Swiften/Jingle/JingleSessionManager.cpp b/Swiften/Jingle/JingleSessionManager.cpp
new file mode 100644
index 0000000..d8630cc
--- /dev/null
+++ b/Swiften/Jingle/JingleSessionManager.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Jingle/JingleSessionManager.h>
+#include <Swiften/Jingle/JingleResponder.h>
+#include <Swiften/Jingle/IncomingJingleSessionHandler.h>
+
+namespace Swift {
+
+JingleSessionManager::JingleSessionManager(IQRouter* router) : router(router) {
+ responder = new JingleResponder(this, router);
+}
+
+JingleSessionManager::~JingleSessionManager() {
+ delete responder;
+}
+
+JingleSession::ref JingleSessionManager::getSession(const JID& jid, const String& id) const {
+ SessionMap::const_iterator i = incomingSessions.find(JIDSession(jid, id));
+ return i != incomingSessions.end() ? i->second : JingleSession::ref();
+}
+
+void JingleSessionManager::addIncomingSessionHandler(IncomingJingleSessionHandler* handler) {
+ incomingSessionHandlers.push_back(handler);
+}
+
+void JingleSessionManager::removeIncomingSessionHandler(IncomingJingleSessionHandler* handler) {
+ incomingSessionHandlers.erase(std::remove(incomingSessionHandlers.begin(), incomingSessionHandlers.end(), handler), incomingSessionHandlers.end());
+}
+
+void JingleSessionManager::handleIncomingSession(const JID& from, IncomingJingleSession::ref session) {
+ incomingSessions.insert(std::make_pair(JIDSession(from, session->getID()), session));
+ foreach (IncomingJingleSessionHandler* handler, incomingSessionHandlers) {
+ if (handler->handleIncomingJingleSession(session)) {
+ return;
+ }
+ }
+ // TODO: Finish session
+}
+
+
+}
diff --git a/Swiften/Jingle/JingleSessionManager.h b/Swiften/Jingle/JingleSessionManager.h
new file mode 100644
index 0000000..ea4199d
--- /dev/null
+++ b/Swiften/Jingle/JingleSessionManager.h
@@ -0,0 +1,49 @@
+/*
+ * 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 <map>
+
+#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Jingle/IncomingJingleSession.h>
+
+namespace Swift {
+ class IQRouter;
+ class JingleResponder;
+ class IncomingJingleSessionHandler;
+
+ class JingleSessionManager {
+ friend class JingleResponder;
+ public:
+ JingleSessionManager(IQRouter* router);
+ ~JingleSessionManager();
+
+ JingleSession::ref getSession(const JID& jid, const String& id) const;
+
+ void addIncomingSessionHandler(IncomingJingleSessionHandler* handler);
+ void removeIncomingSessionHandler(IncomingJingleSessionHandler* handler);
+
+ protected:
+ void handleIncomingSession(const JID& from, IncomingJingleSession::ref);
+
+ private:
+ IQRouter* router;
+ JingleResponder* responder;
+ std::vector<IncomingJingleSessionHandler*> incomingSessionHandlers;
+ struct JIDSession {
+ JIDSession(const JID& jid, const String& session) : jid(jid), session(session) {}
+ bool operator<(const JIDSession& o) const {
+ return jid == o.jid ? session < o.session : jid < o.jid;
+ }
+ JID jid;
+ String session;
+ };
+ typedef std::map<JIDSession, JingleSession::ref> SessionMap;
+ SessionMap incomingSessions;
+ };
+}
diff --git a/Swiften/Jingle/SConscript b/Swiften/Jingle/SConscript
new file mode 100644
index 0000000..c1aadea
--- /dev/null
+++ b/Swiften/Jingle/SConscript
@@ -0,0 +1,11 @@
+Import("swiften_env")
+
+sources = [
+ "IncomingJingleSession.cpp",
+ "IncomingJingleSessionHandler.cpp",
+ "JingleSessionManager.cpp",
+ "JingleResponder.cpp",
+ "JingleSession.cpp",
+ ]
+
+swiften_env.Append(SWIFTEN_OBJECTS = swiften_env.StaticObject(sources))
diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp b/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp
index 6e1082c..bf36321 100644
--- a/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp
+++ b/Swiften/Parser/PayloadParsers/StreamInitiationParser.cpp
@@ -36,7 +36,7 @@ void StreamInitiationParser::handleStartElement(const String& element, const Str
else if (level == PayloadLevel) {
if (element == "file") {
inFile = true;
- currentFile = StreamInitiation::FileInfo();
+ currentFile = StreamInitiationFileInfo();
currentFile.name = attributes.getAttribute("name");
try {
currentFile.size = boost::lexical_cast<int>(attributes.getAttribute("size"));
diff --git a/Swiften/Parser/PayloadParsers/StreamInitiationParser.h b/Swiften/Parser/PayloadParsers/StreamInitiationParser.h
index f01567e..7a44651 100644
--- a/Swiften/Parser/PayloadParsers/StreamInitiationParser.h
+++ b/Swiften/Parser/PayloadParsers/StreamInitiationParser.h
@@ -36,7 +36,7 @@ namespace Swift {
FormParser* formParser;
bool inFile;
bool inFeature;
- StreamInitiation::FileInfo currentFile;
+ StreamInitiationFileInfo currentFile;
String currentText;
};
}
diff --git a/Swiften/SConscript b/Swiften/SConscript
index c325d03..36ebd0c 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -151,6 +151,7 @@ if env["SCONS_STAGE"] == "build" :
"EventLoop",
"Parser",
"JID",
+ "Jingle",
"Disco",
"VCards",
"Network",
diff --git a/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp b/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp
index 71702d0..0c7f593 100644
--- a/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp
+++ b/Swiften/Serializer/PayloadSerializers/StreamInitiationSerializer.cpp
@@ -35,7 +35,7 @@ String StreamInitiationSerializer::serializePayload(boost::shared_ptr<StreamInit
siElement.setAttribute("profile", FILE_TRANSFER_NS);
if (streamInitiation->getFileInfo()) {
- StreamInitiation::FileInfo file = *streamInitiation->getFileInfo();
+ StreamInitiationFileInfo file = *streamInitiation->getFileInfo();
boost::shared_ptr<XMLElement> fileElement(new XMLElement("file", "http://jabber.org/protocol/si/profile/file-transfer"));
fileElement->setAttribute("name", file.name);
if (file.size != -1) {
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp
index 12c8485..e1a13b8 100644
--- a/Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/StreamInitiationSerializerTest.cpp
@@ -21,7 +21,7 @@ class StreamInitiationSerializerTest : public CppUnit::TestFixture{
void testSerialize_Request() {
StreamInitiationSerializer testling;
boost::shared_ptr<StreamInitiation> streamInitiation(new StreamInitiation());
- StreamInitiation::FileInfo fileInfo("test.txt", "This is info about the file.", 1022);
+ StreamInitiationFileInfo fileInfo("test.txt", "This is info about the file.", 1022);
streamInitiation->setID("a0");
streamInitiation->setFileInfo(fileInfo);
streamInitiation->addProvidedMethod("http://jabber.org/protocol/bytestreams");