From 72249383639858b1a7947b1afc6b9491ebd82bf8 Mon Sep 17 00:00:00 2001 From: Tarun Gupta Date: Wed, 29 Jul 2015 21:24:09 +0530 Subject: Completes Jingle. Adds Listenable, JingleSession, JingleContentID, FakeJingleSession, JingleSessionListener, JingleSessionManager, JingleResponder. NotifyListeners are not in line with Swiften and have to be corrected. License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details. Test-Information: None. Change-Id: I6533b2be02a0843277a63ca115348ff6138a0fc0 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 { + + private Vector listeners = new Vector(); + + 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 void notifyListeners(Slot1 event, T1 p1) { + for (T i : listeners) { + event.call(p1); + } + } + + public void notifyListeners(Slot2 event, T1 p1, T2 p2) { + for (T i : listeners) { + event.call(p1, p2); + } + } + + public void notifyListeners(Slot3 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 calledCommands = new Vector(); + 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() { + @Override + public void call(JinglePayload.Reason reason) { + handleSessionTerminateReceived(reason); + } + }, reason); + } + + public void handleSessionAcceptReceived(final JingleContentID id, JingleDescription desc, JingleTransportPayload transport) { + notifyListeners(new Slot3() { + @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() { + @Override + public void call(JingleContentID d, JingleTransportPayload p) { + handleTransportReplaceReceived(d, p); + } + }, id, payload); + } + + public void handleTransportAcceptReceived(final JingleContentID id, JingleTransportPayload payload) { + notifyListeners(new Slot2() { + @Override + public void call(JingleContentID d, JingleTransportPayload p) { + handleTransportAcceptReceived(d, p); + } + }, id, payload); + } + + public void handleTransportInfoReceived(final JingleContentID id, JingleTransportPayload payload) { + notifyListeners(new Slot2() { + @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 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 JingleContentPayload getContentWithDescription(final Vector 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 { + + 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 { + + private JID initiator = new JID(); + private String id = ""; + private Vector listeners = new Vector(); + + 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 , SignalConnection> pendingRequests = new HashMap , 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() { + @Override + public void call(JinglePayload.Reason reason) { + handleSessionTerminateReceived(reason); + } + }, action.getReason());*/ + return; + } + if (JinglePayload.Action.SessionInfo.equals(action.getAction())) { + /*notifyListeners(new Slot1() { + @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() { + @Override + public void call(JingleContentID id, JingleDescription des, JingleTransportPayload tr) { + handleSessionAcceptReceived(id, des, tr); + } + }, contentID, description, transport);*/ + return; + case TransportAccept: + /*notifyListeners(new Slot2() { + @Override + public void call(JingleContentID id, JingleTransportPayload tr) { + handleTransportAcceptReceived(id, tr); + } + }, contentID, transport);*/ + return; + case TransportInfo: + /*notifyListeners(new Slot2() { + @Override + public void call(JingleContentID id, JingleTransportPayload tr) { + handleTransportInfoReceived(id, tr); + } + }, contentID, transport);*/ + return; + case TransportReject: + /*notifyListeners(new Slot2() { + @Override + public void call(JingleContentID id, JingleTransportPayload tr) { + handleTransportRejectReceived(id, tr); + } + }, contentID, transport);*/ + return; + case TransportReplace: + /*notifyListeners(new Slot2() { + @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 request = new GenericRequest(IQ.Type.Set, peerJID, payload, iqRouter); + pendingRequests.put(request, request.onResponse.connect(new Slot2() { + @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 request) { + assert (pendingRequests.containsKey(request)); + if (JinglePayload.Action.TransportInfo.equals(request.getPayloadGeneric().getAction())) { + /*notifyListeners(new Slot1() { + @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 incomingSessionHandlers = new Vector(); + 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 sessions = new HashMap(); + + 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 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 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 extends Request { onResponse.emit(genericPayload, error); } - protected T getPayloadGeneric() { + public T getPayloadGeneric() { return (T)getPayload(); } -- cgit v0.10.2-6-g49f6