From 16a7f31a461f5ea2ff62175952539573e1f37084 Mon Sep 17 00:00:00 2001 From: vanitasvitae Date: Wed, 21 Jun 2017 00:16:47 +0200 Subject: [PATCH] Add sendingThread --- .../IncomingJingleFileOffer.java | 4 - .../JingleFileTransferSession.java | 2 + .../OutgoingJingleFileOffer.java | 86 +++++++++++++++++-- .../smackx/jingle/JingleSession.java | 10 ++- .../JingleTransportInitiationCallback.java | 13 +++ .../transports/JingleTransportManager.java | 4 + .../transports/JingleTransportNegotiator.java | 8 ++ 7 files changed, 116 insertions(+), 11 deletions(-) create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportInitiationCallback.java create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportNegotiator.java diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/IncomingJingleFileOffer.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/IncomingJingleFileOffer.java index 75c02c9bd..e15fe552e 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/IncomingJingleFileOffer.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/IncomingJingleFileOffer.java @@ -51,10 +51,6 @@ public class IncomingJingleFileOffer extends JingleFileTransferSession implement @Override public IQ handleSessionInitiate(Jingle initiate) { - if (role == Role.initiator) { - //TODO: Is tie-break the correct way to tackle this? - return jutil.createErrorTieBreak(initiate); - } if (getState() != State.fresh) { //Out of order (initiate after accept) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferSession.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferSession.java index f499b500b..e46809706 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferSession.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferSession.java @@ -22,6 +22,7 @@ import org.jivesoftware.smackx.jingle.JingleUtil; import org.jivesoftware.smackx.jingle.Role; import org.jivesoftware.smackx.jingle.element.JingleContent; import org.jivesoftware.smackx.jingle.element.JingleContentTransport; +import org.jivesoftware.smackx.jingle.transports.JingleTransportManager; import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransfer; import org.jxmpp.jid.FullJid; @@ -52,6 +53,7 @@ public abstract class JingleFileTransferSession extends JingleSession { protected String name; protected JingleFileTransfer file; protected JingleContentTransport transport; + protected JingleTransportManager transportManager; private final Type type; private State state; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/OutgoingJingleFileOffer.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/OutgoingJingleFileOffer.java index 1129806f6..af104b087 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/OutgoingJingleFileOffer.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/OutgoingJingleFileOffer.java @@ -16,18 +16,25 @@ */ package org.jivesoftware.smackx.jingle_filetransfer; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.logging.Level; import java.util.logging.Logger; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smackx.bytestreams.BytestreamSession; import org.jivesoftware.smackx.jingle.JingleManager; import org.jivesoftware.smackx.jingle.JingleTransportMethodManager; import org.jivesoftware.smackx.jingle.Role; import org.jivesoftware.smackx.jingle.element.Jingle; import org.jivesoftware.smackx.jingle.element.JingleContent; -import org.jivesoftware.smackx.jingle.element.JingleContentTransport; +import org.jivesoftware.smackx.jingle.transports.JingleTransportInitiationCallback; import org.jivesoftware.smackx.jingle.transports.JingleTransportManager; import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransfer; @@ -40,6 +47,10 @@ public class OutgoingJingleFileOffer extends JingleFileTransferSession { private static final Logger LOGGER = Logger.getLogger(OutgoingJingleFileOffer.class.getName()); + private Thread sendingThread; + private File source; + + public OutgoingJingleFileOffer(XMPPConnection connection, FullJid responder, String sid) { super(connection, connection.getUser().asFullJidOrThrow(), responder, Role.initiator, sid, Type.offer); } @@ -50,14 +61,14 @@ public class OutgoingJingleFileOffer extends JingleFileTransferSession { public void sendFile(JingleFileTransfer file, JingleContent.Creator creator, String name) throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException { if (getState() == State.fresh) { - JingleTransportManager transportManager = JingleTransportMethodManager.getInstanceFor(connection) + transportManager = JingleTransportMethodManager.getInstanceFor(connection) .getBestAvailableTransportManager(); if (transportManager == null) { throw new IllegalStateException("There must be at least one workable transport method."); } - JingleContentTransport transport = transportManager.createTransport(); + transport = transportManager.createTransport(); jutil.sendSessionInitiateFileOffer(getResponder(), getSessionId(), creator, name, file, transport); } @@ -65,14 +76,26 @@ public class OutgoingJingleFileOffer extends JingleFileTransferSession { @Override public IQ handleSessionAccept(Jingle sessionAccept) { - //TODO setState(State.active); + + transportManager.initiateOutgoingSession(transport, new JingleTransportInitiationCallback() { + @Override + public void onSessionInitiated(final BytestreamSession session) { + sendingThread = new SendingThread(session, source); + sendingThread.run(); + } + }); + return jutil.createAck(sessionAccept); } @Override public IQ handleSessionTerminate(Jingle sessionTerminate) { - //TODO + + if (sendingThread != null && !sendingThread.isInterrupted()) { + sendingThread.interrupt(); + } + setState(State.terminated); return jutil.createAck(sessionTerminate); } @@ -89,5 +112,58 @@ public class OutgoingJingleFileOffer extends JingleFileTransferSession { transportReplace.getInitiator(), transportReplace.getSid(), creator, name, replacementManager.createTransport()); } + + return jutil.createAck(transportReplace); + } + + private static class SendingThread extends Thread { + + private final BytestreamSession session; + private final File source; + + public SendingThread(BytestreamSession session, File source) { + this.session = session; + this.source = source; + } + + @Override + public void run() { + InputStream inputStream; + OutputStream outputStream; + + try { + inputStream = new FileInputStream(source); + outputStream = session.getOutputStream(); + + byte[] filebuf = new byte[(int) source.length()]; + int r = inputStream.read(filebuf); + + if (r < 0) { + throw new IOException("Read returned -1"); + } + + outputStream.write(filebuf); + } + catch (IOException e) { + LOGGER.log(Level.SEVERE, "Could not send file: " + e, e); + } + finally { + try { + session.close(); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Could not close session.", e); + } + } + } + + @Override + public void interrupt() { + try { + session.close(); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Could not close session.", e); + } + super.interrupt(); + } } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleSession.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleSession.java index fb4d8dc6a..473621a00 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleSession.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleSession.java @@ -121,7 +121,11 @@ public abstract class JingleSession implements JingleSessionHandler { case session_terminate: return handleSessionTerminate(jingle); case transport_replace: - return handleTransportReplace(jingle); + try { + return handleTransportReplace(jingle); + } catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { + e.printStackTrace(); + } default: return IQ.createResultIQ(jingle); } @@ -179,7 +183,9 @@ public abstract class JingleSession implements JingleSessionHandler { return IQ.createResultIQ(transportInfo); } - protected IQ handleTransportReplace(Jingle transportReplace) throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException { + protected IQ handleTransportReplace(Jingle transportReplace) + throws InterruptedException, XMPPException.XMPPErrorException, + SmackException.NotConnectedException, SmackException.NoResponseException { return IQ.createResultIQ(transportReplace); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportInitiationCallback.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportInitiationCallback.java new file mode 100644 index 000000000..964cf2fd0 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportInitiationCallback.java @@ -0,0 +1,13 @@ +package org.jivesoftware.smackx.jingle.transports; + +import org.jivesoftware.smackx.bytestreams.BytestreamSession; + +/** + * Created by vanitas on 20.06.17. + */ +public interface JingleTransportInitiationCallback { + + void onSessionInitiated(BytestreamSession bytestreamSession); + + +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportManager.java index 70f318c5f..108e39a4c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportManager.java @@ -31,4 +31,8 @@ public abstract class JingleTransportManager { public abstract D createTransport(Jingle request); + public abstract void initiateOutgoingSession(JingleContentTransport transport, JingleTransportInitiationCallback callback); + + public abstract void initiateIncomingSession(JingleContentTransport transport, JingleTransportInitiationCallback callback); + } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportNegotiator.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportNegotiator.java new file mode 100644 index 000000000..9d6146cfc --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/JingleTransportNegotiator.java @@ -0,0 +1,8 @@ +package org.jivesoftware.smackx.jingle.transports; + +/** + * Created by vanitas on 20.06.17. + */ +public interface JingleTransportNegotiator { + +}