1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2025-09-12 10:39:38 +02:00

Basic Sending/Receiving Files works again

This commit is contained in:
vanitasvitae 2017-07-29 22:21:36 +02:00
parent af069ffc49
commit 1dbdafe28c
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
9 changed files with 236 additions and 88 deletions

View file

@ -28,6 +28,7 @@ import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.util.Async;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.jingle.Callback;
@ -60,72 +61,11 @@ public class JingleContent implements JingleTransportCallback {
private JingleTransport<?> transport;
private JingleSecurity<?> security;
private JingleTransport<?> replaceTransport = null;
private final List<Callback> callbacks = Collections.synchronizedList(new ArrayList<Callback>());
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 {
pending_accept,
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());
}
/* 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) {
callbacks.add(callback);
}
@ -282,9 +307,29 @@ public class JingleContent implements JingleTransportCallback {
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
public void onTransportReady(BytestreamSession bytestreamSession) {
LOGGER.log(Level.INFO, "TransportReady: " + (isReceiving() ? "Send" : "Receive"));
if (bytestreamSession == null) {
throw new AssertionError("bytestreamSession MUST NOT be null at this point.");
}
@ -330,19 +375,6 @@ public class JingleContent implements JingleTransportCallback {
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() {
return "cont-" + StringUtils.randomString(16);
}

View file

@ -110,6 +110,10 @@ public class JingleSession {
throw new IllegalStateException("Session is not in pending state.");
}
for (JingleContent content : contents.values()) {
content.onAccept(connection);
}
connection.createStanzaCollectorAndSend(createSessionAccept()).nextResultOrThrow();
this.sessionState = SessionState.active;
}

View file

@ -22,6 +22,7 @@ import java.util.List;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackFuture;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.jingle.callbacks.JingleTransportCallback;
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
@ -95,7 +96,7 @@ public abstract class JingleTransport<D extends JingleContentTransportElement> e
return peersProposal;
}
public abstract void handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping);
public abstract IQ handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping);
public void setParent(JingleContent parent) {
if (this.parent != parent) {

View file

@ -16,9 +16,13 @@
*/
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.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
@ -37,6 +41,7 @@ import org.jivesoftware.smackx.jingle.transport.jingle_ibb.element.JingleIBBTran
* Jingle InBandBytestream Transport component.
*/
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 = NAMESPACE_V1;
@ -74,10 +79,11 @@ public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElemen
@Override
public void establishIncomingBytestreamSession(final XMPPConnection connection, final JingleTransportCallback callback, final JingleSession session) {
final InBandBytestreamManager inBandBytestreamManager = InBandBytestreamManager.getByteStreamManager(connection);
LOGGER.log(Level.INFO, "Listen for incoming IBB transports from " + session.getPeer() + ":" + getSid());
InBandBytestreamListener bytestreamListener = new InBandBytestreamListener() {
@Override
public void incomingBytestreamRequest(InBandBytestreamRequest request) {
LOGGER.log(Level.INFO, "Incoming IBB stream: " + request.getFrom().asFullJidIfPossible() + ":" + request.getSessionID());
if (request.getFrom().asFullJidIfPossible().equals(session.getPeer())
&& request.getSessionID().equals(getSid())) {
@ -119,8 +125,8 @@ public class JingleIBBTransport extends JingleTransport<JingleIBBTransportElemen
}
@Override
public void handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping) {
// Nothing to do.
public IQ handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping) {
return IQ.createResultIQ(wrapping);
}
@Override

View file

@ -275,28 +275,30 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
}
@Override
public void handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping) {
public IQ handleTransportInfo(JingleContentTransportInfoElement info, JingleElement wrapping) {
switch (info.getElementName()) {
case JingleS5BTransportInfoElement.CandidateUsed.ELEMENT:
handleCandidateUsed((JingleS5BTransportInfoElement) info, wrapping);
return;
break;
case JingleS5BTransportInfoElement.CandidateActivated.ELEMENT:
handleCandidateActivate((JingleS5BTransportInfoElement) info);
return;
break;
case JingleS5BTransportInfoElement.CandidateError.ELEMENT:
handleCandidateError((JingleS5BTransportInfoElement) info);
return;
break;
case JingleS5BTransportInfoElement.ProxyError.ELEMENT:
handleProxyError((JingleS5BTransportInfoElement) info);
return;
break;
default:
throw new AssertionError("Unknown transport-info element: " + info.getElementName());
}
return IQ.createResultIQ(wrapping);
}
private void handleCandidateUsed(JingleS5BTransportInfoElement info, JingleElement wrapping) {