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 c694b360f..c8ce07963 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 @@ -126,6 +126,11 @@ public class IncomingJingleFileOffer extends JingleFileTransferSession implement return jutil.createAck(transportAccept); } + @Override + public void onTransportMethodFailed(String namespace) { + //Nothing to do. + } + @Override public void acceptIncomingFileOffer(final Jingle request, final File target) { LOGGER.log(Level.INFO, "Client accepted incoming file offer. Try to start receiving."); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileRequest.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileRequest.java index 01683e655..b45d33240 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileRequest.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileRequest.java @@ -41,4 +41,9 @@ public class JingleFileRequest extends JingleFileTransferSession { return new JingleFileRequest(connection, request.getInitiator(), connection.getUser().asFullJidOrThrow(), Role.responder, request.getSid()); } + + @Override + public void onTransportMethodFailed(String namespace) { + //Not implemented + } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferManager.java index 74eaa1662..298228cba 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/JingleFileTransferManager.java @@ -118,8 +118,8 @@ public final class JingleFileTransferManager extends Manager implements JingleHa } //File Request else if (content.getSenders() == JingleContent.Senders.responder) { return JingleFileRequest.createIncomingFileRequest(connection(), request); - - } else { + } + else { // If senders is neither initiator, nor responder, consider session malformed. // See XEP-0166 §6.3 Example 16 and XEP-0234 §4.1 LOGGER.log(Level.WARNING, "Jingle has invalid sender value. Only initiator and responder are allowed."); 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 68f762905..1f46197ca 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 @@ -27,6 +27,7 @@ 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.JingleUtil; import org.jivesoftware.smackx.jingle.Role; import org.jivesoftware.smackx.jingle.element.Jingle; import org.jivesoftware.smackx.jingle.element.JingleContent; @@ -161,4 +162,38 @@ public class OutgoingJingleFileOffer extends JingleFileTransferSession { return jutil.createAck(transportReplace); } + + @Override + public IQ handleTransportAccept(Jingle transportAccept) + throws SmackException.NotConnectedException, InterruptedException { + return handleSessionAccept(transportAccept); + } + + @Override + public void onTransportMethodFailed(String namespace) { + state = State.pending; + JingleContent content = contents.get(0); + failedTransportMethods.add(namespace); + JingleTransportMethodManager tm = JingleTransportMethodManager.getInstanceFor(getConnection()); + JingleTransportManager next = tm.getBestAvailableTransportManager(failedTransportMethods); + + if (next == null) { + //Failure + try { + new JingleUtil(getConnection()).sendSessionTerminateUnsupportedTransports(getRemote(), getSessionId()); + } catch (InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { + LOGGER.log(Level.WARNING, "Could not send session-terminate.", e); + } + return; + } + + //Replace transport + this.transportSession = next.transportSession(this); + try { + jutil.sendTransportReplace(getRemote(), getInitiator(), getSessionId(), content.getCreator(), content.getName(), + transportSession.createTransport()); + } catch (SmackException.NotConnectedException | SmackException.NoResponseException | XMPPException.XMPPErrorException | InterruptedException e) { + LOGGER.log(Level.WARNING, "Could not send transport-replace.", e); + } + } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/ReceiveTask.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/ReceiveTask.java index 2909f62b9..a64a1d956 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/ReceiveTask.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jingle_filetransfer/ReceiveTask.java @@ -56,7 +56,7 @@ public class ReceiveTask implements Runnable { byte[] filebuf = new byte[transfer.getSize()]; int read = 0; byte[] bufbuf = new byte[2048]; - + LOGGER.log(Level.INFO, "Begin receiving."); while (read < filebuf.length) { int r = inputStream.read(bufbuf); if (r >= 0) { @@ -68,6 +68,7 @@ public class ReceiveTask implements Runnable { } outputStream.write(filebuf); + LOGGER.log(Level.INFO, "File successfully received."); } catch (IOException e) { LOGGER.log(Level.SEVERE, "Error while receiving data: ", e); 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 b90f53046..f11302249 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 @@ -17,6 +17,7 @@ package org.jivesoftware.smackx.jingle; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -35,6 +36,7 @@ import org.jxmpp.jid.FullJid; public abstract class JingleSession implements JingleSessionHandler { private static final Logger LOGGER = Logger.getLogger(JingleSession.class.getName()); + protected HashSet failedTransportMethods = new HashSet<>(); protected final FullJid local; @@ -46,7 +48,7 @@ public abstract class JingleSession implements JingleSessionHandler { protected final List contents = new ArrayList<>(); - protected ExecutorService threadPool = Executors.newSingleThreadExecutor(); + protected static ExecutorService threadPool = Executors.newSingleThreadExecutor(); protected ArrayList> queued = new ArrayList<>(); protected JingleTransportSession transportSession; @@ -220,7 +222,7 @@ public abstract class JingleSession implements JingleSessionHandler { return IQ.createResultIQ(securityInfo); } - protected IQ handleTransportAccept(Jingle transportAccept) { + protected IQ handleTransportAccept(Jingle transportAccept) throws SmackException.NotConnectedException, InterruptedException { return IQ.createResultIQ(transportAccept); } @@ -236,4 +238,6 @@ public abstract class JingleSession implements JingleSessionHandler { public abstract XMPPConnection getConnection(); + public abstract void onTransportMethodFailed(String namespace); + } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleTransportMethodManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleTransportMethodManager.java index 38b93a819..19206384b 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleTransportMethodManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleTransportMethodManager.java @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.jingle; import java.util.HashMap; import java.util.Iterator; +import java.util.Set; import java.util.WeakHashMap; import org.jivesoftware.smack.Manager; @@ -106,4 +107,26 @@ public final class JingleTransportMethodManager extends Manager { return null; } + + public JingleTransportManager getBestAvailableTransportManager(Set except) { + JingleTransportManager tm; + for (String ns : transportPreference) { + tm = getTransportManager(ns); + if (tm != null) { + if (except.contains(tm.getNamespace())) { + continue; + } + return tm; + } + } + + for (String ns : transportManagers.keySet()) { + if (except.contains(ns)) { + continue; + } + return getTransportManager(ns); + } + + return null; + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_s5b/JingleS5BTransportSession.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_s5b/JingleS5BTransportSession.java index ad44151f3..c3f14aa85 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_s5b/JingleS5BTransportSession.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/transports/jingle_s5b/JingleS5BTransportSession.java @@ -46,7 +46,7 @@ import org.jivesoftware.smackx.jingle.transports.jingle_s5b.elements.JingleS5BTr import org.jivesoftware.smackx.jingle.transports.jingle_s5b.elements.JingleS5BTransportInfo; /** - * Created by vanitas on 26.06.17. + * Handler that handles Jingle Socks5Bytestream transports (XEP-0260). */ public class JingleS5BTransportSession extends JingleTransportSession { private static final Logger LOGGER = Logger.getLogger(JingleS5BTransportSession.class.getName()); @@ -78,9 +78,9 @@ public class JingleS5BTransportSession extends JingleTransportSession remoteHosts; try { @@ -91,7 +91,7 @@ public class JingleS5BTransportSession extends JingleTransportSession