mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-27 14:32:06 +01:00
IBB sending works using worker thread
This commit is contained in:
parent
5dc37ab239
commit
cb3583e510
9 changed files with 149 additions and 52 deletions
|
@ -70,6 +70,7 @@ public class IncomingJingleFileOffer extends JingleFileTransferSession implement
|
||||||
|
|
||||||
if (state != State.fresh) {
|
if (state != State.fresh) {
|
||||||
//Out of order (initiate after accept)
|
//Out of order (initiate after accept)
|
||||||
|
LOGGER.log(Level.WARNING, "Action " + initiate.getAction() + " is out of order!");
|
||||||
return jutil.createErrorOutOfOrder(initiate);
|
return jutil.createErrorOutOfOrder(initiate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +88,7 @@ public class IncomingJingleFileOffer extends JingleFileTransferSession implement
|
||||||
|
|
||||||
if (transportManager == null) {
|
if (transportManager == null) {
|
||||||
//No usable transports.
|
//No usable transports.
|
||||||
|
LOGGER.log(Level.WARNING, "No usable transports.");
|
||||||
jutil.sendSessionTerminateUnsupportedTransports(initiate.getInitiator(), initiate.getSid());
|
jutil.sendSessionTerminateUnsupportedTransports(initiate.getInitiator(), initiate.getSid());
|
||||||
state = State.terminated;
|
state = State.terminated;
|
||||||
return jutil.createAck(initiate);
|
return jutil.createAck(initiate);
|
||||||
|
@ -106,8 +108,9 @@ public class IncomingJingleFileOffer extends JingleFileTransferSession implement
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IQ handleTransportAccept(Jingle transportAccept) {
|
public IQ handleTransportAccept(Jingle transportAccept) {
|
||||||
|
LOGGER.log(Level.INFO, "Received transport-accept.");
|
||||||
if (state != State.sent_transport_replace) {
|
if (state != State.sent_transport_replace) {
|
||||||
|
LOGGER.log(Level.WARNING, "Session is in state " + state + ", so the transport-accept is out of order.");
|
||||||
return jutil.createErrorOutOfOrder(transportAccept);
|
return jutil.createErrorOutOfOrder(transportAccept);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +122,7 @@ public class IncomingJingleFileOffer extends JingleFileTransferSession implement
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acceptIncomingFileOffer(Jingle request, final File target) {
|
public void acceptIncomingFileOffer(Jingle request, final File target) {
|
||||||
|
LOGGER.log(Level.INFO, "Client accepted incoming file offer. Try to start receiving.");
|
||||||
if (transportManager == null) {
|
if (transportManager == null) {
|
||||||
//Unsupported transport
|
//Unsupported transport
|
||||||
LOGGER.log(Level.WARNING, "Unsupported Transport method.");
|
LOGGER.log(Level.WARNING, "Unsupported Transport method.");
|
||||||
|
@ -132,14 +135,16 @@ public class IncomingJingleFileOffer extends JingleFileTransferSession implement
|
||||||
}
|
}
|
||||||
|
|
||||||
final JingleContentTransport transport = transportManager.createTransport(request);
|
final JingleContentTransport transport = transportManager.createTransport(request);
|
||||||
|
tasks.add(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
try {
|
try {
|
||||||
jutil.sendSessionAccept(getInitiator(), sid, creator, name, JingleContent.Senders.initiator, file, transport);
|
|
||||||
state = State.active;
|
state = State.active;
|
||||||
transportManager.initiateIncomingSession(getInitiator(), transport, new JingleTransportInitiationCallback() {
|
transportManager.initiateIncomingSession(getInitiator(), transport, new JingleTransportInitiationCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSessionInitiated(BytestreamSession bytestreamSession) {
|
public void onSessionInitiated(BytestreamSession bytestreamSession) {
|
||||||
receivingThread = new ReceivingThread(bytestreamSession, file, target);
|
receivingThread = new ReceivingThread(bytestreamSession, file, target);
|
||||||
receivingThread.run();
|
receivingThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -147,10 +152,13 @@ public class IncomingJingleFileOffer extends JingleFileTransferSession implement
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
jutil.sendSessionAccept(getInitiator(), sid, creator, name, JingleContent.Senders.initiator, file, transport);
|
||||||
} catch (SmackException.NotConnectedException | SmackException.NoResponseException | XMPPException.XMPPErrorException | InterruptedException e) {
|
} catch (SmackException.NotConnectedException | SmackException.NoResponseException | XMPPException.XMPPErrorException | InterruptedException e) {
|
||||||
LOGGER.log(Level.SEVERE, "Could not send session-accept: " + e, e);
|
LOGGER.log(Level.SEVERE, "Could not send session-accept: " + e, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void declineIncomingFileOffer(Jingle request) {
|
public void declineIncomingFileOffer(Jingle request) {
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.Manager;
|
import org.jivesoftware.smack.Manager;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
|
@ -47,10 +49,11 @@ import org.jxmpp.jid.FullJid;
|
||||||
* Manager for JingleFileTransfer (XEP-0234).
|
* Manager for JingleFileTransfer (XEP-0234).
|
||||||
*/
|
*/
|
||||||
public final class JingleFileTransferManager extends Manager implements JingleHandler {
|
public final class JingleFileTransferManager extends Manager implements JingleHandler {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(JingleFileTransferManager.class.getName());
|
||||||
|
|
||||||
private static final WeakHashMap<XMPPConnection, JingleFileTransferManager> INSTANCES = new WeakHashMap<>();
|
private static final WeakHashMap<XMPPConnection, JingleFileTransferManager> INSTANCES = new WeakHashMap<>();
|
||||||
private final JingleUtil jutil;
|
|
||||||
private final ArrayList<JingleFileTransferOfferListener> jingleFileTransferOfferListeners = new ArrayList<>();
|
private final ArrayList<JingleFileTransferOfferListener> jingleFileTransferOfferListeners = new ArrayList<>();
|
||||||
|
private final JingleUtil jutil;
|
||||||
|
|
||||||
private JingleFileTransferManager(XMPPConnection connection) {
|
private JingleFileTransferManager(XMPPConnection connection) {
|
||||||
super(connection);
|
super(connection);
|
||||||
|
@ -75,6 +78,7 @@ public final class JingleFileTransferManager extends Manager implements JingleHa
|
||||||
throws InterruptedException, XMPPException.XMPPErrorException,
|
throws InterruptedException, XMPPException.XMPPErrorException,
|
||||||
SmackException.NotConnectedException, SmackException.NoResponseException {
|
SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||||
OutgoingJingleFileOffer offer = new OutgoingJingleFileOffer(connection(), recipient);
|
OutgoingJingleFileOffer offer = new OutgoingJingleFileOffer(connection(), recipient);
|
||||||
|
JingleManager.getInstanceFor(connection()).registerJingleSessionHandler(recipient, offer.getSessionId(), offer);
|
||||||
offer.send(file);
|
offer.send(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,8 +92,6 @@ public final class JingleFileTransferManager extends Manager implements JingleHa
|
||||||
try {
|
try {
|
||||||
handler = createSessionHandler(jingle);
|
handler = createSessionHandler(jingle);
|
||||||
} catch (IllegalArgumentException malformed) {
|
} catch (IllegalArgumentException malformed) {
|
||||||
// If senders is neither initiator, nor responder, consider session malformed.
|
|
||||||
// See XEP-0166 §6.3 Example 16 and XEP-0234 §4.1
|
|
||||||
return jutil.createErrorMalformedRequest(jingle);
|
return jutil.createErrorMalformedRequest(jingle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +107,7 @@ public final class JingleFileTransferManager extends Manager implements JingleHa
|
||||||
*/
|
*/
|
||||||
private JingleFileTransferSession createSessionHandler(Jingle request) {
|
private JingleFileTransferSession createSessionHandler(Jingle request) {
|
||||||
if (request.getAction() != JingleAction.session_initiate) {
|
if (request.getAction() != JingleAction.session_initiate) {
|
||||||
|
LOGGER.log(Level.WARNING, "First received action must be session-initiate.");
|
||||||
throw new IllegalArgumentException("Requests action MUST be session-initiate.");
|
throw new IllegalArgumentException("Requests action MUST be session-initiate.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,8 +118,11 @@ public final class JingleFileTransferManager extends Manager implements JingleHa
|
||||||
} //File Request
|
} //File Request
|
||||||
else if (content.getSenders() == JingleContent.Senders.responder) {
|
else if (content.getSenders() == JingleContent.Senders.responder) {
|
||||||
return JingleFileRequest.createIncomingFileRequest(connection(), request);
|
return JingleFileRequest.createIncomingFileRequest(connection(), request);
|
||||||
} //Malformed 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.");
|
||||||
throw new IllegalArgumentException("Requests content.senders MUST be either responder or initiator.");
|
throw new IllegalArgumentException("Requests content.senders MUST be either responder or initiator.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,15 +43,6 @@ public class OutgoingJingleFileOffer extends JingleFileTransferSession {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(OutgoingJingleFileOffer.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(OutgoingJingleFileOffer.class.getName());
|
||||||
|
|
||||||
public void send(File file) throws InterruptedException, XMPPException.XMPPErrorException,
|
|
||||||
SmackException.NotConnectedException, SmackException.NoResponseException {
|
|
||||||
source = file;
|
|
||||||
String contentName = JingleManager.randomSid();
|
|
||||||
JingleFileTransfer transfer = JingleFileTransferManager.fileTransferFromFile(file);
|
|
||||||
|
|
||||||
initiateFileOffer(transfer, JingleContent.Creator.initiator, contentName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
fresh,
|
fresh,
|
||||||
pending,
|
pending,
|
||||||
|
@ -74,6 +65,15 @@ public class OutgoingJingleFileOffer extends JingleFileTransferSession {
|
||||||
this(connection, recipient, JingleManager.randomSid());
|
this(connection, recipient, JingleManager.randomSid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void send(File file) throws InterruptedException, XMPPException.XMPPErrorException,
|
||||||
|
SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||||
|
source = file;
|
||||||
|
String contentName = JingleManager.randomSid();
|
||||||
|
JingleFileTransfer transfer = JingleFileTransferManager.fileTransferFromFile(file);
|
||||||
|
|
||||||
|
initiateFileOffer(transfer, JingleContent.Creator.initiator, contentName);
|
||||||
|
}
|
||||||
|
|
||||||
public void initiateFileOffer(JingleFileTransfer file, JingleContent.Creator creator, String name) throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException {
|
public void initiateFileOffer(JingleFileTransfer file, JingleContent.Creator creator, String name) throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||||
if (state != State.fresh) {
|
if (state != State.fresh) {
|
||||||
throw new IllegalStateException("This session is not fresh.");
|
throw new IllegalStateException("This session is not fresh.");
|
||||||
|
@ -88,24 +88,30 @@ public class OutgoingJingleFileOffer extends JingleFileTransferSession {
|
||||||
|
|
||||||
transport = transportManager.createTransport(getResponder());
|
transport = transportManager.createTransport(getResponder());
|
||||||
|
|
||||||
jutil.sendSessionInitiateFileOffer(getResponder(), getSessionId(), creator, name, file, transport);
|
|
||||||
state = State.pending;
|
state = State.pending;
|
||||||
|
|
||||||
|
jutil.sendSessionInitiateFileOffer(getResponder(), getSessionId(), creator, name, file, transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IQ handleSessionAccept(Jingle sessionAccept) throws SmackException.NotConnectedException, InterruptedException {
|
public IQ handleSessionAccept(Jingle sessionAccept) throws SmackException.NotConnectedException, InterruptedException {
|
||||||
// Out of order?
|
// Out of order?
|
||||||
if (state != State.pending) {
|
if (state != State.pending) {
|
||||||
LOGGER.log(Level.WARNING, "Out of order!");
|
LOGGER.log(Level.WARNING, "Session state is " + state + ", so session-accept is out of order.");
|
||||||
return jutil.createErrorOutOfOrder(sessionAccept);
|
return jutil.createErrorOutOfOrder(sessionAccept);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.log(Level.INFO, "Session was accepted. Initiate Bytestream.");
|
||||||
state = State.active;
|
state = State.active;
|
||||||
|
tasks.add(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
transportManager.initiateOutgoingSession(getResponder(), transport, new JingleTransportInitiationCallback() {
|
transportManager.initiateOutgoingSession(getResponder(), transport, new JingleTransportInitiationCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSessionInitiated(final BytestreamSession session) {
|
public void onSessionInitiated(final BytestreamSession session) {
|
||||||
|
LOGGER.log(Level.INFO, "BytestreamSession initiated. Start transfer.");
|
||||||
sendingThread = new SendingThread(session, source);
|
sendingThread = new SendingThread(session, source);
|
||||||
sendingThread.run();
|
sendingThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -113,14 +119,18 @@ public class OutgoingJingleFileOffer extends JingleFileTransferSession {
|
||||||
LOGGER.log(Level.SEVERE, "Cannot create outgoing Bytestream session: ", e);
|
LOGGER.log(Level.SEVERE, "Cannot create outgoing Bytestream session: ", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return jutil.createAck(sessionAccept);
|
return jutil.createAck(sessionAccept);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IQ handleSessionTerminate(Jingle sessionTerminate) {
|
public IQ handleSessionTerminate(Jingle sessionTerminate) {
|
||||||
|
LOGGER.log(Level.INFO, "Received session-terminate: " + sessionTerminate.getReason().asEnum());
|
||||||
|
|
||||||
if (sendingThread != null && !sendingThread.isInterrupted()) {
|
if (sendingThread != null && !sendingThread.isInterrupted()) {
|
||||||
|
LOGGER.log(Level.INFO, "Interrupt sending thread.");
|
||||||
sendingThread.interrupt();
|
sendingThread.interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,17 +139,33 @@ public class OutgoingJingleFileOffer extends JingleFileTransferSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IQ handleTransportReplace(Jingle transportReplace)
|
public IQ handleTransportReplace(final Jingle transportReplace)
|
||||||
throws InterruptedException, XMPPException.XMPPErrorException,
|
throws InterruptedException, XMPPException.XMPPErrorException,
|
||||||
SmackException.NotConnectedException, SmackException.NoResponseException {
|
SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||||
JingleTransportManager<?> replacementManager = JingleTransportMethodManager.getInstanceFor(connection)
|
LOGGER.log(Level.INFO, "Received transport-replace.");
|
||||||
|
|
||||||
|
final JingleTransportManager<?> replacementManager = JingleTransportMethodManager.getInstanceFor(connection)
|
||||||
.getTransportManager(transportReplace);
|
.getTransportManager(transportReplace);
|
||||||
|
|
||||||
|
tasks.add(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
if (replacementManager != null) {
|
if (replacementManager != null) {
|
||||||
|
LOGGER.log(Level.INFO, "Accept transport-replace.");
|
||||||
jutil.sendTransportAccept(transportReplace.getFrom().asFullJidOrThrow(),
|
jutil.sendTransportAccept(transportReplace.getFrom().asFullJidOrThrow(),
|
||||||
transportReplace.getInitiator(), transportReplace.getSid(), creator, name,
|
transportReplace.getInitiator(), transportReplace.getSid(), creator, name,
|
||||||
replacementManager.createTransport(getResponder()));
|
replacementManager.createTransport(getResponder()));
|
||||||
|
} else {
|
||||||
|
LOGGER.log(Level.INFO, "Unsupported transport. Reject transport-replace.");
|
||||||
|
jutil.sendTransportReject(transportReplace.getFrom().asFullJidOrThrow(), transportReplace.getInitiator(),
|
||||||
|
transportReplace.getSid(), creator, name, transportReplace.getContents().get(0).getJingleTransport());
|
||||||
}
|
}
|
||||||
|
} catch (InterruptedException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NoResponseException e) {
|
||||||
|
LOGGER.log(Level.SEVERE, "Help me please!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return jutil.createAck(transportReplace);
|
return jutil.createAck(transportReplace);
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,6 +134,14 @@ public class JingleFileTransferChild extends JingleContentDescriptionChildElemen
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the media type of the file.
|
||||||
|
* This is a MIME type from this list:
|
||||||
|
* https://www.iana.org/assignments/media-types/media-types.xhtml
|
||||||
|
* Default should be application/octet-stream.
|
||||||
|
* @param mediaType
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public Builder setMediaType(String mediaType) {
|
public Builder setMediaType(String mediaType) {
|
||||||
this.mediaType = mediaType;
|
this.mediaType = mediaType;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smackx.jingle;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.Manager;
|
import org.jivesoftware.smack.Manager;
|
||||||
|
@ -33,7 +34,6 @@ import org.jivesoftware.smackx.jingle.element.JingleAction;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContent;
|
import org.jivesoftware.smackx.jingle.element.JingleContent;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentDescription;
|
import org.jivesoftware.smackx.jingle.element.JingleContentDescription;
|
||||||
import org.jivesoftware.smackx.jingle.transports.jingle_ibb.JingleIBBTransportManager;
|
import org.jivesoftware.smackx.jingle.transports.jingle_ibb.JingleIBBTransportManager;
|
||||||
import org.jivesoftware.smackx.jingle.transports.jingle_s5b.JingleS5BTransportManager;
|
|
||||||
|
|
||||||
import org.jxmpp.jid.FullJid;
|
import org.jxmpp.jid.FullJid;
|
||||||
|
|
||||||
|
@ -88,19 +88,21 @@ public final class JingleManager extends Manager {
|
||||||
|
|
||||||
if (jingleDescriptionHandler == null) {
|
if (jingleDescriptionHandler == null) {
|
||||||
//Unsupported Application
|
//Unsupported Application
|
||||||
|
LOGGER.log(Level.WARNING, "Unsupported Jingle application.");
|
||||||
return jutil.createSessionTerminateUnsupportedApplications(fullFrom, sid);
|
return jutil.createSessionTerminateUnsupportedApplications(fullFrom, sid);
|
||||||
}
|
}
|
||||||
return jingleDescriptionHandler.handleJingleRequest(jingle);
|
return jingleDescriptionHandler.handleJingleRequest(jingle);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Unknown session
|
//Unknown session
|
||||||
|
LOGGER.log(Level.WARNING, "Unknown session.");
|
||||||
return jutil.createErrorUnknownSession(jingle);
|
return jutil.createErrorUnknownSession(jingle);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
//Register transports.
|
//Register transports.
|
||||||
JingleTransportMethodManager transportMethodManager = JingleTransportMethodManager.getInstanceFor(connection);
|
JingleTransportMethodManager transportMethodManager = JingleTransportMethodManager.getInstanceFor(connection);
|
||||||
transportMethodManager.registerTransportManager(JingleIBBTransportManager.getInstanceFor(connection));
|
transportMethodManager.registerTransportManager(JingleIBBTransportManager.getInstanceFor(connection));
|
||||||
transportMethodManager.registerTransportManager(JingleS5BTransportManager.getInstanceFor(connection));
|
//transportMethodManager.registerTransportManager(JingleS5BTransportManager.getInstanceFor(connection));
|
||||||
}
|
}
|
||||||
|
|
||||||
public JingleHandler registerDescriptionHandler(String namespace, JingleHandler handler) {
|
public JingleHandler registerDescriptionHandler(String namespace, JingleHandler handler) {
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jingle;
|
package org.jivesoftware.smackx.jingle;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
@ -24,6 +28,7 @@ import org.jivesoftware.smackx.jingle.element.Jingle;
|
||||||
import org.jxmpp.jid.FullJid;
|
import org.jxmpp.jid.FullJid;
|
||||||
|
|
||||||
public abstract class JingleSession implements JingleSessionHandler {
|
public abstract class JingleSession implements JingleSessionHandler {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(JingleSession.class.getName());
|
||||||
|
|
||||||
protected final FullJid local;
|
protected final FullJid local;
|
||||||
|
|
||||||
|
@ -33,6 +38,39 @@ public abstract class JingleSession implements JingleSessionHandler {
|
||||||
|
|
||||||
protected final String sid;
|
protected final String sid;
|
||||||
|
|
||||||
|
protected final ConcurrentLinkedQueue<Runnable> tasks = new ConcurrentLinkedQueue<Runnable>() {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(Runnable runnable) {
|
||||||
|
synchronized (tasks) {
|
||||||
|
LOGGER.log(Level.INFO, "Add task.");
|
||||||
|
boolean b = super.add(runnable);
|
||||||
|
tasks.notify();
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final Thread worker = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
synchronized (tasks) {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
tasks.wait();
|
||||||
|
while (!tasks.isEmpty()) {
|
||||||
|
LOGGER.log(Level.INFO, "Run task.");
|
||||||
|
tasks.poll().run();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.log(Level.WARNING, "Interrupted.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public JingleSession(FullJid initiator, FullJid responder, Role role, String sid) {
|
public JingleSession(FullJid initiator, FullJid responder, Role role, String sid) {
|
||||||
if (role == Role.initiator) {
|
if (role == Role.initiator) {
|
||||||
this.local = initiator;
|
this.local = initiator;
|
||||||
|
@ -43,6 +81,7 @@ public abstract class JingleSession implements JingleSessionHandler {
|
||||||
}
|
}
|
||||||
this.sid = sid;
|
this.sid = sid;
|
||||||
this.role = role;
|
this.role = role;
|
||||||
|
worker.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FullJid getInitiator() {
|
public FullJid getInitiator() {
|
||||||
|
|
|
@ -105,7 +105,7 @@ public class JingleUtil {
|
||||||
Jingle jingle = createSessionInitiate(recipient, sessionId, contentCreator, contentName, contentSenders,
|
Jingle jingle = createSessionInitiate(recipient, sessionId, contentCreator, contentName, contentSenders,
|
||||||
description, transport);
|
description, transport);
|
||||||
|
|
||||||
return connection.createStanzaCollectorAndSend(jingle).nextResultOrThrow();
|
return connection.createStanzaCollectorAndSend(jingle).nextResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jingle createSessionAccept(FullJid recipient,
|
public Jingle createSessionAccept(FullJid recipient,
|
||||||
|
@ -148,7 +148,7 @@ public class JingleUtil {
|
||||||
Jingle jingle = createSessionAccept(recipient, sessionId, contentCreator, contentName, contentSenders,
|
Jingle jingle = createSessionAccept(recipient, sessionId, contentCreator, contentName, contentSenders,
|
||||||
description, transport);
|
description, transport);
|
||||||
|
|
||||||
return connection.createStanzaCollectorAndSend(jingle).nextResultOrThrow();
|
return connection.createStanzaCollectorAndSend(jingle).nextResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jingle createSessionTerminate(FullJid recipient, String sessionId, JingleReason reason) {
|
public Jingle createSessionTerminate(FullJid recipient, String sessionId, JingleReason reason) {
|
||||||
|
|
|
@ -122,6 +122,10 @@ public final class Jingle extends IQ {
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JingleReason getReason() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a List of the contents.
|
* Get a List of the contents.
|
||||||
*
|
*
|
||||||
|
|
|
@ -124,6 +124,10 @@ public class JingleReason implements NamedElement {
|
||||||
return xml;
|
return xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Reason asEnum() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class AlternativeSession extends JingleReason {
|
public static class AlternativeSession extends JingleReason {
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue