mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-01 01:35:59 +01:00
Basic Sending/Receiving Files works again
This commit is contained in:
parent
af069ffc49
commit
1dbdafe28c
9 changed files with 236 additions and 88 deletions
|
@ -63,6 +63,18 @@ public abstract class JingleFileTransfer extends JingleDescription<JingleFileTra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void notifyProgressListenersFinished() {
|
||||||
|
for (ProgressListener p : progressListeners) {
|
||||||
|
p.finished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyProgressListenersStarted() {
|
||||||
|
for (ProgressListener p : progressListeners) {
|
||||||
|
p.started();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNamespace() {
|
public String getNamespace() {
|
||||||
return JingleFileTransfer.NAMESPACE;
|
return JingleFileTransfer.NAMESPACE;
|
||||||
|
|
|
@ -17,8 +17,10 @@
|
||||||
package org.jivesoftware.smackx.jft.internal;
|
package org.jivesoftware.smackx.jft.internal;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -41,6 +43,8 @@ public class JingleIncomingFileOffer extends AbstractJingleFileOffer<RemoteFile>
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(JingleIncomingFileOffer.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(JingleIncomingFileOffer.class.getName());
|
||||||
|
|
||||||
|
private File target;
|
||||||
|
|
||||||
public JingleIncomingFileOffer(JingleFileTransferChildElement offer) {
|
public JingleIncomingFileOffer(JingleFileTransferChildElement offer) {
|
||||||
super(new RemoteFile(offer));
|
super(new RemoteFile(offer));
|
||||||
}
|
}
|
||||||
|
@ -52,15 +56,63 @@ public class JingleIncomingFileOffer extends AbstractJingleFileOffer<RemoteFile>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransportReady(BytestreamSession bytestreamSession) {
|
public void onTransportReady(BytestreamSession bytestreamSession) {
|
||||||
InputStream inputStream;
|
LOGGER.log(Level.INFO, "Receive file to " + target.getAbsolutePath());
|
||||||
|
File mFile = target;
|
||||||
|
if (!mFile.exists()) {
|
||||||
|
try {
|
||||||
|
mFile.createNewFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Could not create new File!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream inputStream = null;
|
||||||
|
OutputStream outputStream = null;
|
||||||
try {
|
try {
|
||||||
inputStream = bytestreamSession.getInputStream();
|
inputStream = bytestreamSession.getInputStream();
|
||||||
|
outputStream = new FileOutputStream(mFile);
|
||||||
|
|
||||||
|
byte[] filebuf = new byte[(int) file.getSize()];
|
||||||
|
int read = 0;
|
||||||
|
byte[] bufbuf = new byte[4096];
|
||||||
|
LOGGER.log(Level.INFO, "Begin receiving bytes.");
|
||||||
|
while (read < filebuf.length) {
|
||||||
|
int r = inputStream.read(bufbuf);
|
||||||
|
if (r >= 0) {
|
||||||
|
System.arraycopy(bufbuf, 0, filebuf, read, r);
|
||||||
|
read += r;
|
||||||
|
LOGGER.log(Level.INFO, "Read " + r + " (" + read + " of " + filebuf.length + ") bytes.");
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outputStream.write(filebuf);
|
||||||
|
outputStream.flush();
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.log(Level.SEVERE, "Cannot get InputStream from BytestreamSession: " + e, e);
|
LOGGER.log(Level.SEVERE, "Cannot get InputStream from BytestreamSession: " + e, e);
|
||||||
return;
|
} finally {
|
||||||
|
if (inputStream != null) {
|
||||||
|
try {
|
||||||
|
inputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Could not close InputStream: " + e, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (outputStream != null) {
|
||||||
|
try {
|
||||||
|
outputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Could not close OutputStream: " + e, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyProgressListenersFinished();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOffer() {
|
public boolean isOffer() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -75,6 +127,7 @@ public class JingleIncomingFileOffer extends AbstractJingleFileOffer<RemoteFile>
|
||||||
public Future<Void> accept(XMPPConnection connection, File target)
|
public Future<Void> accept(XMPPConnection connection, File target)
|
||||||
throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException,
|
throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException,
|
||||||
SmackException.NoResponseException {
|
SmackException.NoResponseException {
|
||||||
|
this.target = target;
|
||||||
JingleSession session = getParent().getParent();
|
JingleSession session = getParent().getParent();
|
||||||
if (session.getSessionState() == JingleSession.SessionState.pending) {
|
if (session.getSessionState() == JingleSession.SessionState.pending) {
|
||||||
session.accept(connection);
|
session.accept(connection);
|
||||||
|
|
|
@ -17,6 +17,12 @@
|
||||||
package org.jivesoftware.smackx.jft.internal;
|
package org.jivesoftware.smackx.jft.internal;
|
||||||
|
|
||||||
import java.io.File;
|
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.smackx.bytestreams.BytestreamSession;
|
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
||||||
import org.jivesoftware.smackx.jft.controller.OutgoingFileOfferController;
|
import org.jivesoftware.smackx.jft.controller.OutgoingFileOfferController;
|
||||||
|
@ -28,6 +34,7 @@ import org.jivesoftware.smackx.jingle.element.JingleElement;
|
||||||
* Created by vanitas on 26.07.17.
|
* Created by vanitas on 26.07.17.
|
||||||
*/
|
*/
|
||||||
public class JingleOutgoingFileOffer extends AbstractJingleFileOffer<LocalFile> implements OutgoingFileOfferController {
|
public class JingleOutgoingFileOffer extends AbstractJingleFileOffer<LocalFile> implements OutgoingFileOfferController {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(JingleOutgoingFileOffer.class.getName());
|
||||||
|
|
||||||
public JingleOutgoingFileOffer(File file) {
|
public JingleOutgoingFileOffer(File file) {
|
||||||
super(new LocalFile(file));
|
super(new LocalFile(file));
|
||||||
|
@ -40,7 +47,34 @@ public class JingleOutgoingFileOffer extends AbstractJingleFileOffer<LocalFile>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransportReady(BytestreamSession bytestreamSession) {
|
public void onTransportReady(BytestreamSession bytestreamSession) {
|
||||||
|
File mFile = ((LocalFile) file).getFile();
|
||||||
|
OutputStream outputStream = null;
|
||||||
|
InputStream inputStream = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
outputStream = bytestreamSession.getOutputStream();
|
||||||
|
inputStream = new FileInputStream(mFile);
|
||||||
|
|
||||||
|
byte[] fileBuf = new byte[(int) mFile.length()];
|
||||||
|
|
||||||
|
inputStream.read(fileBuf);
|
||||||
|
|
||||||
|
outputStream.write(fileBuf);
|
||||||
|
outputStream.flush();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Exception while sending file: " + e, e);
|
||||||
|
} finally {
|
||||||
|
if (inputStream != null) {
|
||||||
|
try {
|
||||||
|
inputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Could not close FileInputStream: " + e, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyProgressListenersFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -88,4 +88,8 @@ public class LocalFile extends AbstractJingleFileTransferFile {
|
||||||
public void setHashElement(HashElement hashElement) {
|
public void setHashElement(HashElement hashElement) {
|
||||||
this.hashElement = hashElement;
|
this.hashElement = hashElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public File getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smack.util.Async;
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
||||||
import org.jivesoftware.smackx.jingle.Callback;
|
import org.jivesoftware.smackx.jingle.Callback;
|
||||||
|
@ -60,72 +61,11 @@ public class JingleContent implements JingleTransportCallback {
|
||||||
private JingleTransport<?> transport;
|
private JingleTransport<?> transport;
|
||||||
private JingleSecurity<?> security;
|
private JingleSecurity<?> security;
|
||||||
|
|
||||||
|
private JingleTransport<?> replaceTransport = null;
|
||||||
|
|
||||||
private final List<Callback> callbacks = Collections.synchronizedList(new ArrayList<Callback>());
|
private final List<Callback> callbacks = Collections.synchronizedList(new ArrayList<Callback>());
|
||||||
private final Set<String> transportBlacklist = Collections.synchronizedSet(new HashSet<String>());
|
private final Set<String> transportBlacklist = Collections.synchronizedSet(new HashSet<String>());
|
||||||
|
|
||||||
public IQ handleJingleRequest(JingleElement request, XMPPConnection connection) {
|
|
||||||
switch (request.getAction()) {
|
|
||||||
case content_modify:
|
|
||||||
return handleContentModify(request, connection);
|
|
||||||
case description_info:
|
|
||||||
return handleDescriptionInfo(request, connection);
|
|
||||||
case security_info:
|
|
||||||
return handleSecurityInfo(request, connection);
|
|
||||||
case session_info:
|
|
||||||
return handleSessionInfo(request, connection);
|
|
||||||
case transport_accept:
|
|
||||||
return handleTransportAccept(request, connection);
|
|
||||||
case transport_info:
|
|
||||||
return handleTransportInfo(request, connection);
|
|
||||||
case transport_reject:
|
|
||||||
return handleTransportReject(request, connection);
|
|
||||||
case transport_replace:
|
|
||||||
return handleTransportReplace(request, connection);
|
|
||||||
default:
|
|
||||||
throw new AssertionError("Illegal jingle action: " + request.getAction() + " is not allowed here.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQ handleSessionAccept(JingleElement request, XMPPConnection connection) {
|
|
||||||
return IQ.createResultIQ(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQ handleContentModify(JingleElement request, XMPPConnection connection) {
|
|
||||||
return IQ.createResultIQ(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQ handleDescriptionInfo(JingleElement request, XMPPConnection connection) {
|
|
||||||
return IQ.createResultIQ(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleContentRemove(JingleSession session, XMPPConnection connection) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQ handleSecurityInfo(JingleElement request, XMPPConnection connection) {
|
|
||||||
return IQ.createResultIQ(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQ handleSessionInfo(JingleElement request, XMPPConnection connection) {
|
|
||||||
return IQ.createResultIQ(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQ handleTransportAccept(JingleElement request, XMPPConnection connection) {
|
|
||||||
return IQ.createResultIQ(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQ handleTransportInfo(JingleElement request, XMPPConnection connection) {
|
|
||||||
return IQ.createResultIQ(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQ handleTransportReject(JingleElement request, XMPPConnection connection) {
|
|
||||||
return IQ.createResultIQ(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQ handleTransportReplace(JingleElement request, XMPPConnection connection) {
|
|
||||||
return IQ.createResultIQ(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum STATE {
|
public enum STATE {
|
||||||
pending_accept,
|
pending_accept,
|
||||||
pending_transmission_start,
|
pending_transmission_start,
|
||||||
|
@ -191,6 +131,91 @@ public class JingleContent implements JingleTransportCallback {
|
||||||
return new JingleContent(description, transport, security, content.getName(), content.getDisposition(), content.getCreator(), content.getSenders());
|
return new JingleContent(description, transport, security, content.getName(), content.getDisposition(), content.getCreator(), content.getSenders());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HANDLEXYZ */
|
||||||
|
|
||||||
|
public IQ handleJingleRequest(JingleElement request, XMPPConnection connection) {
|
||||||
|
switch (request.getAction()) {
|
||||||
|
case content_modify:
|
||||||
|
return handleContentModify(request, connection);
|
||||||
|
case description_info:
|
||||||
|
return handleDescriptionInfo(request, connection);
|
||||||
|
case security_info:
|
||||||
|
return handleSecurityInfo(request, connection);
|
||||||
|
case session_info:
|
||||||
|
return handleSessionInfo(request, connection);
|
||||||
|
case transport_accept:
|
||||||
|
return handleTransportAccept(request, connection);
|
||||||
|
case transport_info:
|
||||||
|
return handleTransportInfo(request, connection);
|
||||||
|
case transport_reject:
|
||||||
|
return handleTransportReject(request, connection);
|
||||||
|
case transport_replace:
|
||||||
|
return handleTransportReplace(request, connection);
|
||||||
|
default:
|
||||||
|
throw new AssertionError("Illegal jingle action: " + request.getAction() + " is not allowed here.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleContentAccept(JingleElement request, XMPPConnection connection) {
|
||||||
|
onAccept(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IQ handleSessionAccept(JingleElement request, XMPPConnection connection) {
|
||||||
|
LOGGER.log(Level.INFO, "RECEIVED SESSION ACCEPT!");
|
||||||
|
onAccept(connection);
|
||||||
|
return IQ.createResultIQ(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ handleContentModify(JingleElement request, XMPPConnection connection) {
|
||||||
|
return IQ.createResultIQ(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ handleDescriptionInfo(JingleElement request, XMPPConnection connection) {
|
||||||
|
return IQ.createResultIQ(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleContentRemove(JingleSession session, XMPPConnection connection) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ handleSecurityInfo(JingleElement request, XMPPConnection connection) {
|
||||||
|
return IQ.createResultIQ(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ handleSessionInfo(JingleElement request, XMPPConnection connection) {
|
||||||
|
return IQ.createResultIQ(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ handleTransportAccept(JingleElement request, XMPPConnection connection) {
|
||||||
|
if (replaceTransport == null) {
|
||||||
|
LOGGER.log(Level.WARNING, "Received transport-accept, but apparently we did not try to replace the transport.");
|
||||||
|
return JingleElement.createJingleErrorOutOfOrder(request);
|
||||||
|
}
|
||||||
|
transport = replaceTransport;
|
||||||
|
|
||||||
|
onAccept(connection);
|
||||||
|
|
||||||
|
return IQ.createResultIQ(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ handleTransportInfo(JingleElement request, XMPPConnection connection) {
|
||||||
|
assert request.getContents().size() == 1;
|
||||||
|
JingleContentElement content = request.getContents().get(0);
|
||||||
|
|
||||||
|
return transport.handleTransportInfo(content.getTransport().getInfo(), request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ handleTransportReject(JingleElement request, XMPPConnection connection) {
|
||||||
|
return IQ.createResultIQ(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IQ handleTransportReplace(JingleElement request, XMPPConnection connection) {
|
||||||
|
return IQ.createResultIQ(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MISCELLANEOUS */
|
||||||
|
|
||||||
public void addCallback(Callback callback) {
|
public void addCallback(Callback callback) {
|
||||||
callbacks.add(callback);
|
callbacks.add(callback);
|
||||||
}
|
}
|
||||||
|
@ -282,9 +307,29 @@ public class JingleContent implements JingleTransportCallback {
|
||||||
getSenders() == JingleContentElement.Senders.both;
|
getSenders() == JingleContentElement.Senders.both;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onAccept(final XMPPConnection connection) {
|
||||||
|
//Establish transport
|
||||||
|
Async.go(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
if (isReceiving()) {
|
||||||
|
LOGGER.log(Level.INFO, "Establish incoming bytestream.");
|
||||||
|
getTransport().establishIncomingBytestreamSession(connection, JingleContent.this, getParent());
|
||||||
|
} else if (isSending()) {
|
||||||
|
LOGGER.log(Level.INFO, "Establish outgoing bytestream.");
|
||||||
|
getTransport().establishOutgoingBytestreamSession(connection, JingleContent.this, getParent());
|
||||||
|
}
|
||||||
|
} catch (SmackException.NotConnectedException | InterruptedException e) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Error establishing connection: " + e, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTransportReady(BytestreamSession bytestreamSession) {
|
public void onTransportReady(BytestreamSession bytestreamSession) {
|
||||||
|
LOGGER.log(Level.INFO, "TransportReady: " + (isReceiving() ? "Send" : "Receive"));
|
||||||
if (bytestreamSession == null) {
|
if (bytestreamSession == null) {
|
||||||
throw new AssertionError("bytestreamSession MUST NOT be null at this point.");
|
throw new AssertionError("bytestreamSession MUST NOT be null at this point.");
|
||||||
}
|
}
|
||||||
|
@ -330,19 +375,6 @@ public class JingleContent implements JingleTransportCallback {
|
||||||
connection.createStanzaCollectorAndSend(transportReplace).nextResultOrThrow();
|
connection.createStanzaCollectorAndSend(transportReplace).nextResultOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleContentAccept(JingleElement request, XMPPConnection connection) {
|
|
||||||
//Establish transport
|
|
||||||
try {
|
|
||||||
if (isReceiving()) {
|
|
||||||
getTransport().establishIncomingBytestreamSession(connection, this, getParent());
|
|
||||||
} else if (isSending()) {
|
|
||||||
getTransport().establishOutgoingBytestreamSession(connection, this, getParent());
|
|
||||||
}
|
|
||||||
} catch (SmackException.NotConnectedException | InterruptedException e) {
|
|
||||||
LOGGER.log(Level.SEVERE, "Error establishing connection: " + e, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String randomName() {
|
public static String randomName() {
|
||||||
return "cont-" + StringUtils.randomString(16);
|
return "cont-" + StringUtils.randomString(16);
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,10 @@ public class JingleSession {
|
||||||
throw new IllegalStateException("Session is not in pending state.");
|
throw new IllegalStateException("Session is not in pending state.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (JingleContent content : contents.values()) {
|
||||||
|
content.onAccept(connection);
|
||||||
|
}
|
||||||
|
|
||||||
connection.createStanzaCollectorAndSend(createSessionAccept()).nextResultOrThrow();
|
connection.createStanzaCollectorAndSend(createSessionAccept()).nextResultOrThrow();
|
||||||
this.sessionState = SessionState.active;
|
this.sessionState = SessionState.active;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.util.List;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.SmackFuture;
|
import org.jivesoftware.smack.SmackFuture;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
||||||
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
|
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
|
||||||
|
@ -95,7 +96,7 @@ public abstract class JingleTransport<D extends JingleContentTransportElement> e
|
||||||
return peersProposal;
|
return peersProposal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping);
|
public abstract IQ handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping);
|
||||||
|
|
||||||
public void setParent(JingleContent parent) {
|
public void setParent(JingleContent parent) {
|
||||||
if (this.parent != parent) {
|
if (this.parent != parent) {
|
||||||
|
|
|
@ -16,9 +16,13 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jingle.transport.jingle_ibb;
|
package org.jivesoftware.smackx.jingle.transport.jingle_ibb;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
|
||||||
|
@ -37,6 +41,7 @@ import org.jivesoftware.smackx.jingle.transport.jingle_ibb.element.JingleIBBTran
|
||||||
* Jingle InBandBytestream Transport component.
|
* Jingle InBandBytestream Transport component.
|
||||||
*/
|
*/
|
||||||
public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElement> {
|
public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElement> {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(JingleIBBTransport.class.getName());
|
||||||
|
|
||||||
public static final String NAMESPACE_V1 = "urn:xmpp:jingle:transports:ibb:1";
|
public static final String NAMESPACE_V1 = "urn:xmpp:jingle:transports:ibb:1";
|
||||||
public static final String NAMESPACE = NAMESPACE_V1;
|
public static final String NAMESPACE = NAMESPACE_V1;
|
||||||
|
@ -74,10 +79,11 @@ public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElemen
|
||||||
@Override
|
@Override
|
||||||
public void establishIncomingBytestreamSession(final XMPPConnection connection, final JingleTransportCallback callback, final JingleSession session) {
|
public void establishIncomingBytestreamSession(final XMPPConnection connection, final JingleTransportCallback callback, final JingleSession session) {
|
||||||
final InBandBytestreamManager inBandBytestreamManager = InBandBytestreamManager.getByteStreamManager(connection);
|
final InBandBytestreamManager inBandBytestreamManager = InBandBytestreamManager.getByteStreamManager(connection);
|
||||||
|
LOGGER.log(Level.INFO, "Listen for incoming IBB transports from " + session.getPeer() + ":" + getSid());
|
||||||
InBandBytestreamListener bytestreamListener = new InBandBytestreamListener() {
|
InBandBytestreamListener bytestreamListener = new InBandBytestreamListener() {
|
||||||
@Override
|
@Override
|
||||||
public void incomingBytestreamRequest(InBandBytestreamRequest request) {
|
public void incomingBytestreamRequest(InBandBytestreamRequest request) {
|
||||||
|
LOGGER.log(Level.INFO, "Incoming IBB stream: " + request.getFrom().asFullJidIfPossible() + ":" + request.getSessionID());
|
||||||
if (request.getFrom().asFullJidIfPossible().equals(session.getPeer())
|
if (request.getFrom().asFullJidIfPossible().equals(session.getPeer())
|
||||||
&& request.getSessionID().equals(getSid())) {
|
&& request.getSessionID().equals(getSid())) {
|
||||||
|
|
||||||
|
@ -119,8 +125,8 @@ public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping) {
|
public IQ handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping) {
|
||||||
// Nothing to do.
|
return IQ.createResultIQ(wrapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -275,28 +275,30 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping) {
|
public IQ handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping) {
|
||||||
switch (info.getElementName()) {
|
switch (info.getElementName()) {
|
||||||
|
|
||||||
case JingleS5BTransportInfoElement.CandidateUsed.ELEMENT:
|
case JingleS5BTransportInfoElement.CandidateUsed.ELEMENT:
|
||||||
handleCandidateUsed((JingleS5BTransportInfoElement) info, wrapping);
|
handleCandidateUsed((JingleS5BTransportInfoElement) info, wrapping);
|
||||||
return;
|
break;
|
||||||
|
|
||||||
case JingleS5BTransportInfoElement.CandidateActivated.ELEMENT:
|
case JingleS5BTransportInfoElement.CandidateActivated.ELEMENT:
|
||||||
handleCandidateActivate((JingleS5BTransportInfoElement) info);
|
handleCandidateActivate((JingleS5BTransportInfoElement) info);
|
||||||
return;
|
break;
|
||||||
|
|
||||||
case JingleS5BTransportInfoElement.CandidateError.ELEMENT:
|
case JingleS5BTransportInfoElement.CandidateError.ELEMENT:
|
||||||
handleCandidateError((JingleS5BTransportInfoElement) info);
|
handleCandidateError((JingleS5BTransportInfoElement) info);
|
||||||
return;
|
break;
|
||||||
|
|
||||||
case JingleS5BTransportInfoElement.ProxyError.ELEMENT:
|
case JingleS5BTransportInfoElement.ProxyError.ELEMENT:
|
||||||
handleProxyError((JingleS5BTransportInfoElement) info);
|
handleProxyError((JingleS5BTransportInfoElement) info);
|
||||||
return;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new AssertionError("Unknown transport-info element: " + info.getElementName());
|
throw new AssertionError("Unknown transport-info element: " + info.getElementName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return IQ.createResultIQ(wrapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleCandidateUsed(JingleS5BTransportInfoElement info, JingleElement wrapping) {
|
private void handleCandidateUsed(JingleS5BTransportInfoElement info, JingleElement wrapping) {
|
||||||
|
|
Loading…
Reference in a new issue