summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/isode')
-rwxr-xr-xsrc/com/isode/stroke/base/Listenable.java59
-rw-r--r--src/com/isode/stroke/jingle/AbstractJingleSessionListener.java54
-rw-r--r--src/com/isode/stroke/jingle/FakeJingleSession.java210
-rw-r--r--src/com/isode/stroke/jingle/IncomingJingleSessionHandler.java22
-rw-r--r--src/com/isode/stroke/jingle/Jingle.java28
-rw-r--r--src/com/isode/stroke/jingle/JingleContentID.java33
-rw-r--r--src/com/isode/stroke/jingle/JingleResponder.java70
-rw-r--r--src/com/isode/stroke/jingle/JingleSession.java53
-rw-r--r--src/com/isode/stroke/jingle/JingleSessionImpl.java265
-rw-r--r--src/com/isode/stroke/jingle/JingleSessionListener.java28
-rw-r--r--src/com/isode/stroke/jingle/JingleSessionManager.java83
-rw-r--r--src/com/isode/stroke/queries/GenericRequest.java4
12 files changed, 907 insertions, 2 deletions
diff --git a/src/com/isode/stroke/base/Listenable.java b/src/com/isode/stroke/base/Listenable.java
new file mode 100755
index 0000000..c0aa091
--- /dev/null
+++ b/src/com/isode/stroke/base/Listenable.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.base;
+
+import java.util.Vector;
+import com.isode.stroke.signals.Slot;
+import com.isode.stroke.signals.Slot1;
+import com.isode.stroke.signals.Slot2;
+import com.isode.stroke.signals.Slot3;
+
+public class Listenable<T> {
+
+ private Vector<T> listeners = new Vector<T>();
+
+ public void addListener(T listener) {
+ listeners.add(listener);
+ }
+
+ public void removeListener(T listener) {
+ while(listeners.contains(listener)) {
+ listeners.remove(listener);
+ }
+ }
+
+ //Swiften code calls event(i), which is not yet done.
+ public void notifyListeners(Slot event) {
+ for (T i : listeners) {
+ event.call();
+ }
+ }
+
+ //Swiften code calls event(i), which is not yet done.
+ public <T1> void notifyListeners(Slot1<T1> event, T1 p1) {
+ for (T i : listeners) {
+ event.call(p1);
+ }
+ }
+
+ public <T1, T2> void notifyListeners(Slot2<T1, T2> event, T1 p1, T2 p2) {
+ for (T i : listeners) {
+ event.call(p1, p2);
+ }
+ }
+
+ public <T1, T2, T3> void notifyListeners(Slot3<T1, T2, T3> event, T1 p1, T2 p2, T3 p3) {
+ for (T i : listeners) {
+ event.call(p1, p2, p3);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/jingle/AbstractJingleSessionListener.java b/src/com/isode/stroke/jingle/AbstractJingleSessionListener.java
new file mode 100644
index 0000000..6c76922
--- /dev/null
+++ b/src/com/isode/stroke/jingle/AbstractJingleSessionListener.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.jingle;
+
+import com.isode.stroke.elements.JinglePayload;
+import com.isode.stroke.elements.JingleDescription;
+import com.isode.stroke.elements.JingleTransportPayload;
+import java.util.logging.Logger;
+
+public class AbstractJingleSessionListener implements JingleSessionListener {
+
+ private Logger logger_ = Logger.getLogger(this.getClass().getName());
+
+ public void handleSessionAcceptReceived(final JingleContentID id, JingleDescription des, JingleTransportPayload tr) {
+ logger_.warning("Unimplemented\n");
+ }
+
+ public void handleSessionInfoReceived(JinglePayload payload) {
+ logger_.warning("Unimplemented\n");
+ }
+
+ public void handleSessionTerminateReceived(JinglePayload.Reason reason) {
+ logger_.warning("Unimplemented\n");
+ }
+
+ public void handleTransportAcceptReceived(final JingleContentID id, JingleTransportPayload tr) {
+ logger_.warning("Unimplemented\n");
+ }
+
+ public void handleTransportInfoReceived(final JingleContentID id, JingleTransportPayload tr) {
+ logger_.warning("Unimplemented\n");
+ }
+
+ public void handleTransportRejectReceived(final JingleContentID id, JingleTransportPayload tr) {
+ logger_.warning("Unimplemented\n");
+ }
+
+ public void handleTransportReplaceReceived(final JingleContentID id, JingleTransportPayload tr) {
+ logger_.warning("Unimplemented\n");
+ }
+
+ public void handleTransportInfoAcknowledged(final String id) {
+
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/jingle/FakeJingleSession.java b/src/com/isode/stroke/jingle/FakeJingleSession.java
new file mode 100644
index 0000000..927c262
--- /dev/null
+++ b/src/com/isode/stroke/jingle/FakeJingleSession.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2011 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+/*
+ * Copyright (c) 2013-2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.jingle;
+
+import com.isode.stroke.elements.JinglePayload;
+import com.isode.stroke.elements.JingleDescription;
+import com.isode.stroke.elements.JingleTransportPayload;
+import com.isode.stroke.elements.Payload;
+import com.isode.stroke.jingle.JingleContentID;
+import com.isode.stroke.jingle.JingleSession;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.base.SimpleIDGenerator;
+import com.isode.stroke.signals.Slot1;
+import com.isode.stroke.signals.Slot2;
+import com.isode.stroke.signals.Slot3;
+import java.util.Vector;
+
+public class FakeJingleSession extends JingleSession {
+
+ public interface Command {
+
+ }
+
+ public class InitiateCall implements Command {
+ public InitiateCall(JingleContentID contentId, JingleDescription desc, JingleTransportPayload payL) {
+ this.id = contentId;
+ this.description = desc;
+ this.payload = payL;
+ }
+ public JingleContentID id;
+ public JingleDescription description;
+ public JingleTransportPayload payload;
+ };
+
+ public class TerminateCall implements Command {
+ public TerminateCall(JinglePayload.Reason.Type r) {
+ this.reason = r;
+ }
+ public JinglePayload.Reason.Type reason;
+ };
+
+ public class InfoCall implements Command {
+ public InfoCall(Payload info){
+ this.payload = info;
+ }
+ public Payload payload;
+ };
+
+ public class AcceptCall implements Command {
+ public AcceptCall(JingleContentID contentId, JingleDescription desc, JingleTransportPayload payL) {
+ this.id = contentId;
+ this.description = desc;
+ this.payload = payL;
+ }
+ public JingleContentID id;
+ public JingleDescription description;
+ public JingleTransportPayload payload;
+ };
+
+ public class InfoTransportCall implements Command {
+ public InfoTransportCall(JingleContentID contentId, JingleTransportPayload payL) {
+ this.id = contentId;
+ this.payload = payL;
+ }
+ public JingleContentID id;
+ public JingleTransportPayload payload;
+ };
+
+ public class AcceptTransportCall implements Command {
+ public AcceptTransportCall(JingleContentID contentId, JingleTransportPayload payL) {
+ this.id = contentId;
+ this.payload = payL;
+ }
+ public JingleContentID id;
+ public JingleTransportPayload payload;
+ };
+
+ public class RejectTransportCall implements Command {
+ public RejectTransportCall(JingleContentID contentId, JingleTransportPayload payL) {
+ this.id = contentId;
+ this.payload = payL;
+ }
+ public JingleContentID id;
+ public JingleTransportPayload payload;
+ };
+
+ public class ReplaceTransportCall implements Command {
+ public ReplaceTransportCall(JingleContentID contentId, JingleTransportPayload payL) {
+ this.id = contentId;
+ this.payload = payL;
+ }
+ public JingleContentID id;
+ public JingleTransportPayload payload;
+ };
+
+ public Vector<Command> calledCommands = new Vector<Command>();
+ public SimpleIDGenerator idGenerator = new SimpleIDGenerator();
+
+ public FakeJingleSession(final JID initiator, final String id) {
+ super(initiator, id);
+ }
+
+ public void sendInitiate(final JingleContentID id, JingleDescription desc, JingleTransportPayload payload) {
+ calledCommands.add(new InitiateCall(id, desc, payload));
+ }
+
+ public void sendTerminate(JinglePayload.Reason.Type reason) {
+ calledCommands.add(new TerminateCall(reason));
+ }
+
+ public void sendInfo(Payload payload) {
+ calledCommands.add(new InfoCall(payload));
+ }
+
+ public void sendAccept(final JingleContentID id, JingleDescription desc) {
+ sendAccept(id, desc, null);
+ }
+
+ public void sendAccept(final JingleContentID id, JingleDescription desc, JingleTransportPayload payload) {
+ calledCommands.add(new AcceptCall(id, desc, payload));
+ }
+
+ public String sendTransportInfo(final JingleContentID id, JingleTransportPayload payload) {
+ calledCommands.add(new InfoTransportCall(id, payload));
+ return idGenerator.generateID();
+ }
+
+ public void sendTransportAccept(final JingleContentID id, JingleTransportPayload payload) {
+ calledCommands.add(new AcceptTransportCall(id, payload));
+ }
+
+ public void sendTransportReject(final JingleContentID id, JingleTransportPayload payload) {
+ calledCommands.add(new RejectTransportCall(id, payload));
+ }
+
+ public void sendTransportReplace(final JingleContentID id, JingleTransportPayload payload) {
+ calledCommands.add(new ReplaceTransportCall(id, payload));
+ }
+
+ public void handleSessionTerminateReceived(final JinglePayload.Reason reason) {
+ notifyListeners(new Slot1<JinglePayload.Reason>() {
+ @Override
+ public void call(JinglePayload.Reason reason) {
+ handleSessionTerminateReceived(reason);
+ }
+ }, reason);
+ }
+
+ public void handleSessionAcceptReceived(final JingleContentID id, JingleDescription desc, JingleTransportPayload transport) {
+ notifyListeners(new Slot3<JingleContentID, JingleDescription, JingleTransportPayload>() {
+ @Override
+ public void call(JingleContentID d, JingleDescription n, JingleTransportPayload p) {
+ handleSessionAcceptReceived(d, n, p);
+ }
+ }, id, desc, transport);
+ }
+
+ public void handleSessionInfoReceived(JinglePayload payload) {
+
+ }
+
+ public void handleTransportReplaceReceived(final JingleContentID id, JingleTransportPayload payload) {
+ notifyListeners(new Slot2<JingleContentID, JingleTransportPayload>() {
+ @Override
+ public void call(JingleContentID d, JingleTransportPayload p) {
+ handleTransportReplaceReceived(d, p);
+ }
+ }, id, payload);
+ }
+
+ public void handleTransportAcceptReceived(final JingleContentID id, JingleTransportPayload payload) {
+ notifyListeners(new Slot2<JingleContentID, JingleTransportPayload>() {
+ @Override
+ public void call(JingleContentID d, JingleTransportPayload p) {
+ handleTransportAcceptReceived(d, p);
+ }
+ }, id, payload);
+ }
+
+ public void handleTransportInfoReceived(final JingleContentID id, JingleTransportPayload payload) {
+ notifyListeners(new Slot2<JingleContentID, JingleTransportPayload>() {
+ @Override
+ public void call(JingleContentID d, JingleTransportPayload p) {
+ handleTransportInfoReceived(d, p);
+ }
+ }, id, payload);
+ }
+
+ public void handleTransportRejectReceived(final JingleContentID id, JingleTransportPayload payload) {
+
+ }
+
+ public void handleTransportInfoAcknowledged(final String id) {
+
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/jingle/IncomingJingleSessionHandler.java b/src/com/isode/stroke/jingle/IncomingJingleSessionHandler.java
new file mode 100644
index 0000000..72d27bd
--- /dev/null
+++ b/src/com/isode/stroke/jingle/IncomingJingleSessionHandler.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2011-2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.jingle;
+
+import com.isode.stroke.jingle.JingleSession;
+import com.isode.stroke.elements.JingleContentPayload;
+import com.isode.stroke.jid.JID;
+import java.util.Vector;
+
+public interface IncomingJingleSessionHandler {
+
+ public boolean handleIncomingJingleSession(JingleSession session, final Vector<JingleContentPayload> contents, final JID recipient);
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/jingle/Jingle.java b/src/com/isode/stroke/jingle/Jingle.java
new file mode 100644
index 0000000..14dbb68
--- /dev/null
+++ b/src/com/isode/stroke/jingle/Jingle.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2011 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.jingle;
+
+import com.isode.stroke.elements.JingleContentPayload;
+import com.isode.stroke.elements.Payload;
+import java.util.Vector;
+
+public class Jingle {
+
+ public <T extends Payload> JingleContentPayload getContentWithDescription(final Vector<JingleContentPayload> contents, T payload) {
+ for (int i = 0; i < contents.size(); ++i) {
+ if (contents.get(i).getDescription(payload) != null) {
+ return contents.get(i);
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/com/isode/stroke/jingle/JingleContentID.java b/src/com/isode/stroke/jingle/JingleContentID.java
new file mode 100644
index 0000000..ef959e6
--- /dev/null
+++ b/src/com/isode/stroke/jingle/JingleContentID.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2011-2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.jingle;
+
+import com.isode.stroke.elements.JingleContentPayload;
+
+public class JingleContentID {
+
+ private String name = "";
+ private JingleContentPayload.Creator creator;
+
+ public JingleContentID(final String name, JingleContentPayload.Creator creator) {
+ this.name = name;
+ this.creator = creator;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public JingleContentPayload.Creator getCreator() {
+ return this.creator;
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/jingle/JingleResponder.java b/src/com/isode/stroke/jingle/JingleResponder.java
new file mode 100644
index 0000000..7c45e0d
--- /dev/null
+++ b/src/com/isode/stroke/jingle/JingleResponder.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2011-2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.jingle;
+
+import com.isode.stroke.queries.SetResponder;
+import com.isode.stroke.queries.IQRouter;
+import com.isode.stroke.elements.JinglePayload;
+import com.isode.stroke.elements.ErrorPayload;
+import com.isode.stroke.jid.JID;
+import java.util.logging.Logger;
+
+public class JingleResponder extends SetResponder<JinglePayload> {
+
+ private JingleSessionManager sessionManager;
+ private IQRouter router;
+ private Logger logger_ = Logger.getLogger(this.getClass().getName());
+
+ public JingleResponder(JingleSessionManager sessionManager, IQRouter router) {
+ super(new JinglePayload(), router);
+ this.sessionManager = sessionManager;
+ this.router = router;
+ }
+
+ public boolean handleSetRequest(final JID from, final JID to, final String id, JinglePayload payload) {
+ if (JinglePayload.Action.SessionInitiate.equals(payload.getAction())) {
+ if (sessionManager.getSession(from, payload.getSessionID()) != null) {
+ // TODO: Add tie-break error
+ sendError(from, id, ErrorPayload.Condition.Conflict, ErrorPayload.Type.Cancel);
+ }
+ else {
+ sendResponse(from, id, null);
+ if (!payload.getInitiator().isBare()) {
+ JingleSessionImpl session = new JingleSessionImpl(payload.getInitiator(), from, payload.getSessionID(), router);
+ sessionManager.handleIncomingSession(from, to, session, payload.getContents());
+ } else {
+ logger_.fine("Unable to create Jingle session due to initiator not being a full JID.\n");
+ }
+ }
+ }
+ else {
+ JingleSessionImpl session = null;
+ if (payload.getInitiator().isValid()) {
+ logger_.fine("Lookup session by initiator.\n");
+ session = sessionManager.getSession(payload.getInitiator(), payload.getSessionID());
+ } else {
+ logger_.fine("Lookup session by from attribute.\n");
+ session = sessionManager.getSession(from, payload.getSessionID());
+ }
+ if (session != null) {
+ session.handleIncomingAction(payload);
+ sendResponse(from, id, null);
+ }
+ else {
+ logger_.warning("Didn't find jingle session!");
+ // TODO: Add jingle-specific error
+ sendError(from, id, ErrorPayload.Condition.ItemNotFound, ErrorPayload.Type.Cancel);
+ }
+ }
+ return true;
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/jingle/JingleSession.java b/src/com/isode/stroke/jingle/JingleSession.java
new file mode 100644
index 0000000..38ee9cd
--- /dev/null
+++ b/src/com/isode/stroke/jingle/JingleSession.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011-2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.jingle;
+
+import com.isode.stroke.elements.JinglePayload;
+import com.isode.stroke.elements.JingleDescription;
+import com.isode.stroke.elements.JingleTransportPayload;
+import com.isode.stroke.elements.Payload;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.base.Listenable;
+import java.util.Vector;
+
+public abstract class JingleSession extends Listenable<JingleSessionListener> {
+
+ private JID initiator = new JID();
+ private String id = "";
+ private Vector<JingleSessionListener> listeners = new Vector<JingleSessionListener>();
+
+ public JingleSession(final JID initiator, final String id) {
+ this.initiator = initiator;
+ this.id = id;
+ // initiator must always be a full JID; session lookup based on it wouldn't work otherwise
+ // this is checked on an upper level so that the assert never fails
+ assert(!initiator.isBare());
+ }
+
+ public JID getInitiator() {
+ return initiator;
+ }
+
+ public String getID() {
+ return id;
+ }
+
+ public abstract void sendInitiate(final JingleContentID id, JingleDescription description, JingleTransportPayload transport);
+ public abstract void sendTerminate(JinglePayload.Reason.Type reason);
+ public abstract void sendInfo(Payload payload);
+ public abstract void sendAccept(final JingleContentID id, JingleDescription description);
+ public abstract void sendAccept(final JingleContentID id, JingleDescription description, JingleTransportPayload transport);
+ public abstract String sendTransportInfo(final JingleContentID id, JingleTransportPayload transport);
+ public abstract void sendTransportAccept(final JingleContentID id, JingleTransportPayload transport);
+ public abstract void sendTransportReject(final JingleContentID id, JingleTransportPayload transport);
+ public abstract void sendTransportReplace(final JingleContentID id, JingleTransportPayload transport);
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/jingle/JingleSessionImpl.java b/src/com/isode/stroke/jingle/JingleSessionImpl.java
new file mode 100644
index 0000000..8ce60d7
--- /dev/null
+++ b/src/com/isode/stroke/jingle/JingleSessionImpl.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2011-2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.jingle;
+
+import java.util.logging.Logger;
+import java.util.Map;
+import java.util.HashMap;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.queries.GenericRequest;
+import com.isode.stroke.queries.IQRouter;
+import com.isode.stroke.signals.SignalConnection;
+import com.isode.stroke.signals.Slot1;
+import com.isode.stroke.signals.Slot2;
+import com.isode.stroke.signals.Slot3;
+import com.isode.stroke.elements.JinglePayload;
+import com.isode.stroke.elements.JingleDescription;
+import com.isode.stroke.elements.JingleTransportPayload;
+import com.isode.stroke.elements.JingleContentPayload;
+import com.isode.stroke.elements.Payload;
+import com.isode.stroke.elements.ErrorPayload;
+import com.isode.stroke.elements.IQ;
+
+public class JingleSessionImpl extends JingleSession {
+
+ private IQRouter iqRouter;
+ private JID peerJID;
+ private Map<GenericRequest<JinglePayload> , SignalConnection> pendingRequests = new HashMap<GenericRequest<JinglePayload> , SignalConnection>();
+ private Logger logger_ = Logger.getLogger(this.getClass().getName());
+
+ public JingleSessionImpl(final JID initiator, final JID peerJID, final String id, IQRouter router) {
+ super(initiator, id);
+ this.iqRouter = router;
+ this.peerJID = peerJID;
+ logger_.fine("initiator: " + initiator + ", peerJID: " + peerJID + "\n");
+ }
+
+ public void sendInitiate(final JingleContentID id, JingleDescription description, JingleTransportPayload transport) {
+ JinglePayload payload = new JinglePayload(JinglePayload.Action.SessionInitiate, getID());
+ payload.setInitiator(getInitiator());
+ JingleContentPayload content = new JingleContentPayload();
+ content.setCreator(id.getCreator());
+ content.setName(id.getName());
+ content.addDescription(description);
+ content.addTransport(transport);
+ payload.addPayload(content);
+
+ sendSetRequest(payload);
+ }
+
+ public void sendTerminate(JinglePayload.Reason.Type reason) {
+ JinglePayload payload = new JinglePayload(JinglePayload.Action.SessionTerminate, getID());
+ payload.setReason(new JinglePayload.Reason(reason));
+ payload.setInitiator(getInitiator());
+ sendSetRequest(payload);
+ }
+
+ public void sendInfo(Payload info) {
+ JinglePayload payload = new JinglePayload(JinglePayload.Action.SessionInfo, getID());
+ payload.addPayload(info);
+
+ sendSetRequest(payload);
+ }
+
+ public void sendAccept(final JingleContentID id, JingleDescription description) {
+ sendAccept(id, description, null);
+ }
+
+ public void sendAccept(final JingleContentID id, JingleDescription description, JingleTransportPayload transPayload) {
+ JinglePayload payload = createPayload();
+
+ JingleContentPayload content = new JingleContentPayload();
+ content.setCreator(id.getCreator());
+ content.setName(id.getName());
+ content.addTransport(transPayload);
+ content.addDescription(description);
+ payload.setAction(JinglePayload.Action.SessionAccept);
+ payload.addPayload(content);
+
+ // put into IQ:set and send it away
+ sendSetRequest(payload);
+ }
+
+ public String sendTransportInfo(final JingleContentID id, JingleTransportPayload transPayload) {
+ JinglePayload payload = createPayload();
+
+ JingleContentPayload content = new JingleContentPayload();
+ content.setCreator(id.getCreator());
+ content.setName(id.getName());
+ content.addTransport(transPayload);
+ payload.setAction(JinglePayload.Action.TransportInfo);
+ payload.addPayload(content);
+
+ return sendSetRequest(payload);
+ }
+
+ public void sendTransportAccept(final JingleContentID id, JingleTransportPayload transPayload) {
+ JinglePayload payload = createPayload();
+
+ JingleContentPayload content = new JingleContentPayload();
+ content.setCreator(id.getCreator());
+ content.setName(id.getName());
+ content.addTransport(transPayload);
+ payload.setAction(JinglePayload.Action.TransportAccept);
+ payload.addPayload(content);
+
+ // put into IQ:set and send it away
+ sendSetRequest(payload);
+ }
+
+ public void sendTransportReject(final JingleContentID id, JingleTransportPayload transPayload) {
+ JinglePayload payload = createPayload();
+
+ JingleContentPayload content = new JingleContentPayload();
+ content.setCreator(id.getCreator());
+ content.setName(id.getName());
+ content.addTransport(transPayload);
+ payload.setAction(JinglePayload.Action.TransportReject);
+ payload.addPayload(content);
+
+ sendSetRequest(payload);
+ }
+
+ public void sendTransportReplace(final JingleContentID id, JingleTransportPayload transPayload) {
+ JinglePayload payload = createPayload();
+
+ JingleContentPayload content = new JingleContentPayload();
+ content.setCreator(id.getCreator());
+ content.setName(id.getName());
+ content.addTransport(transPayload);
+ payload.setAction(JinglePayload.Action.TransportReplace);
+ payload.addContent(content);
+
+ sendSetRequest(payload);
+ }
+
+ void handleIncomingAction(JinglePayload action) {
+ if (JinglePayload.Action.SessionTerminate.equals(action.getAction())) {
+ /*notifyListeners(new Slot1<JinglePayload.Reason>() {
+ @Override
+ public void call(JinglePayload.Reason reason) {
+ handleSessionTerminateReceived(reason);
+ }
+ }, action.getReason());*/
+ return;
+ }
+ if (JinglePayload.Action.SessionInfo.equals(action.getAction())) {
+ /*notifyListeners(new Slot1<JinglePayload>() {
+ @Override
+ public void call(JinglePayload p) {
+ handleSessionInfoReceived(p);
+ }
+ }, action);*/
+ return;
+ }
+
+ JingleContentPayload content = action.getPayload(new JingleContentPayload());
+ if (content == null) {
+ logger_.fine("no content payload!\n");
+ return;
+ }
+ JingleContentID contentID = new JingleContentID(content.getName(), content.getCreator());
+ JingleDescription description = content.getDescriptions().isEmpty() ? null : content.getDescriptions().get(0);
+ JingleTransportPayload transport = content.getTransports().isEmpty() ? null : content.getTransports().get(0);
+ switch(action.getAction()) {
+ case SessionAccept:
+ /*notifyListeners(new Slot3<JingleContentID, JingleDescription, JingleTransportPayload>() {
+ @Override
+ public void call(JingleContentID id, JingleDescription des, JingleTransportPayload tr) {
+ handleSessionAcceptReceived(id, des, tr);
+ }
+ }, contentID, description, transport);*/
+ return;
+ case TransportAccept:
+ /*notifyListeners(new Slot2<JingleContentID, JingleTransportPayload>() {
+ @Override
+ public void call(JingleContentID id, JingleTransportPayload tr) {
+ handleTransportAcceptReceived(id, tr);
+ }
+ }, contentID, transport);*/
+ return;
+ case TransportInfo:
+ /*notifyListeners(new Slot2<JingleContentID, JingleTransportPayload>() {
+ @Override
+ public void call(JingleContentID id, JingleTransportPayload tr) {
+ handleTransportInfoReceived(id, tr);
+ }
+ }, contentID, transport);*/
+ return;
+ case TransportReject:
+ /*notifyListeners(new Slot2<JingleContentID, JingleTransportPayload>() {
+ @Override
+ public void call(JingleContentID id, JingleTransportPayload tr) {
+ handleTransportRejectReceived(id, tr);
+ }
+ }, contentID, transport);*/
+ return;
+ case TransportReplace:
+ /*notifyListeners(new Slot2<JingleContentID, JingleTransportPayload>() {
+ @Override
+ public void call(JingleContentID id, JingleTransportPayload tr) {
+ handleTransportReplaceReceived(id, tr);
+ }
+ }, contentID, transport);*/
+ return;
+ // following unused Jingle actions
+ case ContentAccept:
+ case ContentAdd:
+ case ContentModify:
+ case ContentReject:
+ case ContentRemove:
+ case DescriptionInfo:
+ case SecurityInfo:
+
+ // handled elsewhere
+ case SessionInitiate:
+ case SessionInfo:
+ case SessionTerminate:
+
+ case UnknownAction:
+ return;
+ }
+ assert(false);
+ }
+
+ private String sendSetRequest(JinglePayload payload) {
+ final GenericRequest<JinglePayload> request = new GenericRequest<JinglePayload>(IQ.Type.Set, peerJID, payload, iqRouter);
+ pendingRequests.put(request, request.onResponse.connect(new Slot2<JinglePayload, ErrorPayload>() {
+ @Override
+ public void call(JinglePayload p, ErrorPayload e) {
+ handleRequestResponse(request);
+ }
+ }));
+ return request.send();
+ }
+
+ private JinglePayload createPayload() {
+ JinglePayload payload = new JinglePayload();
+ payload.setSessionID(getID());
+ payload.setInitiator(getInitiator());
+ return payload;
+ }
+
+ private void handleRequestResponse(GenericRequest<JinglePayload> request) {
+ assert (pendingRequests.containsKey(request));
+ if (JinglePayload.Action.TransportInfo.equals(request.getPayloadGeneric().getAction())) {
+ /*notifyListeners(new Slot1<String>() {
+ @Override
+ public void call(String s) {
+ handleTransportInfoAcknowledged(s);
+ }
+ }, request.getID());*/
+ }
+ pendingRequests.get(request).disconnect();
+ pendingRequests.remove(request);
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/jingle/JingleSessionListener.java b/src/com/isode/stroke/jingle/JingleSessionListener.java
new file mode 100644
index 0000000..b68d865
--- /dev/null
+++ b/src/com/isode/stroke/jingle/JingleSessionListener.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.jingle;
+
+import com.isode.stroke.elements.JinglePayload;
+import com.isode.stroke.elements.JingleDescription;
+import com.isode.stroke.elements.JingleTransportPayload;
+
+public interface JingleSessionListener {
+
+ public void handleSessionAcceptReceived(final JingleContentID id, JingleDescription des, JingleTransportPayload tr);
+ public void handleSessionInfoReceived(JinglePayload payload);
+ public void handleSessionTerminateReceived(JinglePayload.Reason reason);
+ public void handleTransportAcceptReceived(final JingleContentID id, JingleTransportPayload tr);
+ public void handleTransportInfoReceived(final JingleContentID id, JingleTransportPayload tr);
+ public void handleTransportRejectReceived(final JingleContentID id, JingleTransportPayload tr);
+ public void handleTransportReplaceReceived(final JingleContentID id, JingleTransportPayload tr);
+ public void handleTransportInfoAcknowledged(final String id);
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/jingle/JingleSessionManager.java b/src/com/isode/stroke/jingle/JingleSessionManager.java
new file mode 100644
index 0000000..284e8cd
--- /dev/null
+++ b/src/com/isode/stroke/jingle/JingleSessionManager.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2011-2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.jingle;
+
+import java.util.logging.Logger;
+import java.util.Vector;
+import java.util.Map;
+import java.util.HashMap;
+import com.isode.stroke.queries.IQRouter;
+import com.isode.stroke.elements.JingleContentPayload;
+import com.isode.stroke.jid.JID;
+
+public class JingleSessionManager {
+
+ private IQRouter router;
+ private JingleResponder responder;
+ private Vector<IncomingJingleSessionHandler> incomingSessionHandlers = new Vector<IncomingJingleSessionHandler>();
+ private Logger logger_ = Logger.getLogger(this.getClass().getName());
+
+ private class JIDSession {
+ public JIDSession(final JID initiator, final String session) {
+ this.initiator = initiator;
+ this.session = session;
+ }
+ public int compareTo(JIDSession other) {
+ if(other == null) {
+ return -1;
+ }
+ if (initiator.equals(other.initiator)) {
+ return session.compareTo(other.session);
+ }
+ else {
+ return initiator.compareTo(other.initiator);
+ }
+ }
+ public JID initiator;
+ public String session;
+ };
+
+ private Map<JIDSession, JingleSessionImpl> sessions = new HashMap<JIDSession, JingleSessionImpl>();
+
+ public JingleSessionManager(IQRouter router) {
+ this.router = router;
+ responder = new JingleResponder(this, router);
+ responder.start();
+ }
+
+ public JingleSessionImpl getSession(final JID jid, final String id) {
+ return sessions.get(new JIDSession(jid, id));
+ }
+
+ public void addIncomingSessionHandler(IncomingJingleSessionHandler handler) {
+ incomingSessionHandlers.add(handler);
+ }
+
+ public void removeIncomingSessionHandler(IncomingJingleSessionHandler handler) {
+ incomingSessionHandlers.remove(handler);
+ }
+
+ public void registerOutgoingSession(final JID initiator, JingleSessionImpl session) {
+ sessions.put(new JIDSession(initiator, session.getID()), session);
+ logger_.fine("Added session " + session.getID() + " for initiator " + initiator.toString() + "\n");
+ }
+
+ protected void handleIncomingSession(final JID initiator, final JID recipient, JingleSessionImpl session, final Vector<JingleContentPayload> contents) {
+ sessions.put(new JIDSession(initiator, session.getID()), session);
+ for (IncomingJingleSessionHandler handler : incomingSessionHandlers) {
+ if (handler.handleIncomingJingleSession(session, contents, recipient)) {
+ return;
+ }
+ }
+ // TODO: Finish session
+ }
+} \ No newline at end of file
diff --git a/src/com/isode/stroke/queries/GenericRequest.java b/src/com/isode/stroke/queries/GenericRequest.java
index a885ca0..c35b369 100644
--- a/src/com/isode/stroke/queries/GenericRequest.java
+++ b/src/com/isode/stroke/queries/GenericRequest.java
@@ -27,7 +27,7 @@ public class GenericRequest<T extends Payload> extends Request {
}
@Override
- protected void handleResponse(Payload payload, ErrorPayload error) {
+ public void handleResponse(Payload payload, ErrorPayload error) {
T genericPayload = null;
try {
genericPayload = (T)payload;
@@ -37,7 +37,7 @@ public class GenericRequest<T extends Payload> extends Request {
onResponse.emit(genericPayload, error);
}
- protected T getPayloadGeneric() {
+ public T getPayloadGeneric() {
return (T)getPayload();
}