summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften')
-rw-r--r--Swiften/Elements/WhiteboardPayload.h15
-rw-r--r--Swiften/Parser/PayloadParsers/WhiteboardParser.cpp11
-rw-r--r--Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h3
-rw-r--r--Swiften/Whiteboard/WhiteboardResponder.cpp25
-rw-r--r--Swiften/Whiteboard/WhiteboardResponder.h2
-rw-r--r--Swiften/Whiteboard/WhiteboardSession.cpp17
-rw-r--r--Swiften/Whiteboard/WhiteboardSession.h6
-rw-r--r--Swiften/Whiteboard/WhiteboardSessionManager.cpp36
-rw-r--r--Swiften/Whiteboard/WhiteboardSessionManager.h12
9 files changed, 115 insertions, 12 deletions
diff --git a/Swiften/Elements/WhiteboardPayload.h b/Swiften/Elements/WhiteboardPayload.h
index 8d40d9d..db261ca 100644
--- a/Swiften/Elements/WhiteboardPayload.h
+++ b/Swiften/Elements/WhiteboardPayload.h
@@ -13,7 +13,11 @@
namespace Swift {
class WhiteboardPayload : public Payload {
public:
- WhiteboardPayload() {
+ typedef boost::shared_ptr<WhiteboardPayload> ref;
+
+ enum Type {Data, SessionRequest};
+
+ WhiteboardPayload(Type type = WhiteboardPayload::Data) : type_(type) {
}
void setData(const std::string &data) {
@@ -24,7 +28,16 @@ namespace Swift {
return data_;
}
+ Type getType() const {
+ return type_;
+ }
+
+ void setType(Type type) {
+ type_ = type;
+ }
+
private:
std::string data_;
+ Type type_;
};
}
diff --git a/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp b/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
index 77e5c2c..94b67e5 100644
--- a/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
+++ b/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
@@ -10,12 +10,21 @@ namespace Swift {
WhiteboardParser::WhiteboardParser() : level_(0) {
}
void WhiteboardParser::handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) {
+ if (level_ == 0) {
+ std::string type = attributes.getAttribute("type");
+ if (type.empty()) {
+ getPayloadInternal()->setType(WhiteboardPayload::Data);
+ }
+ else if (type == "request") {
+ getPayloadInternal()->setType(WhiteboardPayload::SessionRequest);
+ }
+ }
++level_;
}
void WhiteboardParser::handleEndElement(const std::string& element, const std::string&) {
--level_;
- if(level_ == 0) {
+ if (level_ == 0) {
getPayloadInternal()->setData(data_);
}
}
diff --git a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h
index a7d04f1..9b7f905 100644
--- a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h
+++ b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.h
@@ -15,6 +15,9 @@ namespace Swift {
std::string serializePayload(boost::shared_ptr<WhiteboardPayload> payload) const {
XMLElement element("wb");
element.addNode(XMLTextNode::ref(new XMLTextNode(payload->getData())));
+ if (payload->getType() == WhiteboardPayload::SessionRequest) {
+ element.setAttribute("type", "request");
+ }
return element.serialize();
}
};
diff --git a/Swiften/Whiteboard/WhiteboardResponder.cpp b/Swiften/Whiteboard/WhiteboardResponder.cpp
index 2e4905a..8a1b290 100644
--- a/Swiften/Whiteboard/WhiteboardResponder.cpp
+++ b/Swiften/Whiteboard/WhiteboardResponder.cpp
@@ -15,11 +15,28 @@ namespace Swift {
}
bool WhiteboardResponder::handleSetRequest(const JID& from, const JID& to, const std::string& id, boost::shared_ptr<WhiteboardPayload> payload) {
- sendResponse(from, id, boost::shared_ptr<WhiteboardPayload>());
- WhiteboardSession* session = sessionManager_->getSession(from.toBare());
- if (session != NULL) {
- session->handleIncomingAction(payload);
+ if (payload->getType() == WhiteboardPayload::SessionRequest) {
+ sessionManager_->onRequestReceived(from);
+ sessionRequests_[from] = id;
+ } else {
+ sendResponse(from, id, boost::shared_ptr<WhiteboardPayload>());
+ WhiteboardSession* session = sessionManager_->getSession(from.toBare());
+ if (session != NULL) {
+ session->handleIncomingAction(payload);
+ }
}
return true;
}
+
+ void WhiteboardResponder::sendRequestResponse(const JID& contact, bool accepted) {
+ if (sessionRequests_.find(contact) == sessionRequests_.end()) {
+ return;
+ }
+ if (accepted ) {
+ sendResponse(contact, sessionRequests_[contact], boost::shared_ptr<WhiteboardPayload>());
+ } else {
+ sendError(contact, sessionRequests_[contact], ErrorPayload::Conflict, ErrorPayload::Cancel);
+ }
+ sessionRequests_.erase(contact);
+ }
}
diff --git a/Swiften/Whiteboard/WhiteboardResponder.h b/Swiften/Whiteboard/WhiteboardResponder.h
index b171ef3..d1b712d 100644
--- a/Swiften/Whiteboard/WhiteboardResponder.h
+++ b/Swiften/Whiteboard/WhiteboardResponder.h
@@ -17,8 +17,10 @@ namespace Swift {
public:
WhiteboardResponder(WhiteboardSessionManager* sessionManager, IQRouter* router);
bool handleSetRequest(const JID& from, const JID& to, const std::string& id, boost::shared_ptr<WhiteboardPayload> payload);
+ void sendRequestResponse(const JID& contact, bool accepted);
private:
+ std::map<JID, std::string> sessionRequests_;
WhiteboardSessionManager* sessionManager_;
IQRouter* router_;
};
diff --git a/Swiften/Whiteboard/WhiteboardSession.cpp b/Swiften/Whiteboard/WhiteboardSession.cpp
index 7d95af0..859f2cd 100644
--- a/Swiften/Whiteboard/WhiteboardSession.cpp
+++ b/Swiften/Whiteboard/WhiteboardSession.cpp
@@ -6,9 +6,10 @@
#include <Swiften/Whiteboard/WhiteboardSession.h>
+#include <boost/bind.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Elements/WhiteboardPayload.h>
-#include <Swiften/Queries/GenericRequest.h>
+#include <Swiften/Elements/ErrorPayload.h>
#include <iostream>
@@ -26,4 +27,18 @@ namespace Swift {
boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_);
request->send();
}
+
+ void WhiteboardSession::sendSessionRequest() {
+ boost::shared_ptr<WhiteboardPayload> payload = boost::make_shared<WhiteboardPayload>(WhiteboardPayload::SessionRequest);
+ sessionRequest = new GenericRequest<WhiteboardPayload>(IQ::Set, toJID_, payload, router_);
+ sessionRequest->onResponse.connect(boost::bind(&WhiteboardSession::handleSessionRequestResponse, this, _1, _2));
+ sessionRequest->send();
+ }
+
+ void WhiteboardSession::handleSessionRequestResponse(boost::shared_ptr<WhiteboardPayload> whiteboardPayload, boost::shared_ptr<ErrorPayload> errorPayload) {
+ if (errorPayload.get() == 0) {
+ onRequestAccepted(toJID_, this);
+ }
+ delete sessionRequest;
+ }
}
diff --git a/Swiften/Whiteboard/WhiteboardSession.h b/Swiften/Whiteboard/WhiteboardSession.h
index c36e729..14d6778 100644
--- a/Swiften/Whiteboard/WhiteboardSession.h
+++ b/Swiften/Whiteboard/WhiteboardSession.h
@@ -10,9 +10,11 @@
#include <Swiften/JID/JID.h>
#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Queries/GenericRequest.h>
namespace Swift {
class IQRouter;
+ class ErrorPayload;
class WhiteboardPayload;
class WhiteboardSession {
@@ -20,12 +22,16 @@ namespace Swift {
WhiteboardSession(const JID& jid, IQRouter* router);
void handleIncomingAction(boost::shared_ptr<WhiteboardPayload> payload);
void sendData(const std::string& data);
+ void sendSessionRequest();
+ void handleSessionRequestResponse(boost::shared_ptr<WhiteboardPayload> whiteboardPayload, boost::shared_ptr<ErrorPayload> errorPayload);
public:
boost::signal< void(const std::string& data)> onDataReceived;
+ boost::signal< void(const JID& contact, WhiteboardSession* session)> onRequestAccepted;
private:
JID toJID_;
IQRouter* router_;
+ GenericRequest<WhiteboardPayload>* sessionRequest;
};
}
diff --git a/Swiften/Whiteboard/WhiteboardSessionManager.cpp b/Swiften/Whiteboard/WhiteboardSessionManager.cpp
index 3b82cda..ccbc4d7 100644
--- a/Swiften/Whiteboard/WhiteboardSessionManager.cpp
+++ b/Swiften/Whiteboard/WhiteboardSessionManager.cpp
@@ -7,6 +7,7 @@
#include <Swiften/Whiteboard/WhiteboardSessionManager.h>
+#include <boost/bind.hpp>
#include <Swiften/Queries/IQRouter.h>
#include <Swiften/Whiteboard/WhiteboardSession.h>
#include <Swiften/Whiteboard/WhiteboardResponder.h>
@@ -24,18 +25,45 @@ namespace Swift {
}
WhiteboardSession* WhiteboardSessionManager::getSession(const JID& to) {
- if (sessions_.find(to) == sessions_.end()) {
+ if (sessions_.find(to.toBare()) == sessions_.end()) {
return NULL;
}
- return sessions_[to];
+ return sessions_[to.toBare()];
}
WhiteboardSession* WhiteboardSessionManager::createSession(const JID& to) {
- WhiteboardSession* session = new WhiteboardSession(getFullJID(to), router_);
- sessions_[to] = session;
+ JID fullJID = to;
+ if (fullJID.isBare()) {
+ fullJID = getFullJID(fullJID);
+ }
+ WhiteboardSession* session = new WhiteboardSession(fullJID, router_);
+ sessions_[to.toBare()] = session;
+ return session;
+ }
+
+ WhiteboardSession* WhiteboardSessionManager::acceptSession(const JID& to) {
+ responder->sendRequestResponse(to, true);
+ WhiteboardSession* session = getSession(to);
+ if (session == NULL) {
+ return createSession(to);
+ }
return session;
}
+ void WhiteboardSessionManager::requestSession(const JID& to) {
+ WhiteboardSession* session = createSession(to);
+ session->onRequestAccepted.connect(boost::bind(&WhiteboardSessionManager::handleRequestAccepted, this, _1, _2));
+ session->sendSessionRequest();
+ }
+
+ void WhiteboardSessionManager::cancelSession(const JID& to) {
+ responder->sendRequestResponse(to, false);
+ }
+
+ void WhiteboardSessionManager::handleRequestAccepted(const JID& contact, WhiteboardSession* session) {
+ onRequestAccepted(contact, session);
+ }
+
JID WhiteboardSessionManager::getFullJID(const JID& bareJID) {
std::vector<Presence::ref> presences = presenceOracle_->getAllPresence(bareJID);
return presences[0]->getFrom();
diff --git a/Swiften/Whiteboard/WhiteboardSessionManager.h b/Swiften/Whiteboard/WhiteboardSessionManager.h
index 93d2f19..3cd3aab 100644
--- a/Swiften/Whiteboard/WhiteboardSessionManager.h
+++ b/Swiften/Whiteboard/WhiteboardSessionManager.h
@@ -10,6 +10,7 @@
#include <Swiften/Queries/IQRouter.h>
#include <Swiften/JID/JID.h>
+#include <Swiften/Base/boost_bsignals.h>
namespace Swift {
class IQRouter;
@@ -23,9 +24,18 @@ namespace Swift {
~WhiteboardSessionManager();
WhiteboardSession* getSession(const JID& to);
- WhiteboardSession* createSession(const JID& to);
+ WhiteboardSession* acceptSession(const JID& to);
+ void requestSession(const JID& to);
+ void cancelSession(const JID& to);
+ void handleRequestAccepted(const JID& contact, WhiteboardSession* session);
+
+ public:
+ boost::signal< void (const JID&)> onRequestReceived;
+ boost::signal< void (const JID&, WhiteboardSession*)> onRequestAccepted;
+
private:
JID getFullJID(const JID& bareJID);
+ WhiteboardSession* createSession(const JID& to);
private:
std::map<JID, WhiteboardSession*> sessions_;