mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-24 04:52:05 +01:00
First state representing stuff
This commit is contained in:
parent
1912ebb8d0
commit
e0a54c19d6
9 changed files with 221 additions and 18 deletions
|
@ -16,7 +16,15 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jingle_filetransfer;
|
package org.jivesoftware.smackx.jingle_filetransfer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smackx.jingle.JingleManager;
|
||||||
import org.jivesoftware.smackx.jingle.Role;
|
import org.jivesoftware.smackx.jingle.Role;
|
||||||
|
import org.jivesoftware.smackx.jingle.element.Jingle;
|
||||||
|
import org.jivesoftware.smackx.jingle_filetransfer.callback.IncomingFileOfferCallback;
|
||||||
|
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransfer;
|
||||||
|
|
||||||
import org.jxmpp.jid.FullJid;
|
import org.jxmpp.jid.FullJid;
|
||||||
|
|
||||||
|
@ -25,7 +33,43 @@ import org.jxmpp.jid.FullJid;
|
||||||
*/
|
*/
|
||||||
public class JingleFileOffer extends JingleFileTransferSession {
|
public class JingleFileOffer extends JingleFileTransferSession {
|
||||||
|
|
||||||
public JingleFileOffer(FullJid initiator, FullJid responder, Role role, String sid) {
|
public JingleFileOffer(XMPPConnection connection, FullJid initiator, FullJid responder, Role role, String sid) {
|
||||||
super(initiator, responder, role, sid, Type.offer);
|
super(connection, initiator, responder, role, sid, Type.offer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JingleFileOffer createOutgoingFileOffer(XMPPConnection connection, FullJid recipient) {
|
||||||
|
return new JingleFileOffer(connection, connection.getUser().asFullJidOrThrow(), recipient,
|
||||||
|
Role.initiator, JingleManager.randomSid());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JingleFileOffer createIncomingFileOffer(XMPPConnection connection, Jingle request) {
|
||||||
|
return new JingleFileOffer(connection, request.getInitiator(), connection.getUser().asFullJidOrThrow(),
|
||||||
|
Role.responder, request.getSid());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IQ handleSessionInitiate(Jingle initiate) {
|
||||||
|
if (role == Role.initiator) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getState() != State.fresh) {
|
||||||
|
return jutil.createErrorOutOfOrder(initiate);
|
||||||
|
}
|
||||||
|
|
||||||
|
IncomingFileOfferCallback callback = new IncomingFileOfferCallback() {
|
||||||
|
@Override
|
||||||
|
public void accept(JingleFileTransfer file, File target) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decline() {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
JingleFileTransferManager.getInstanceFor(connection).notifyIncomingFileOffer(initiate, callback);
|
||||||
|
return jutil.createAck(initiate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jingle_filetransfer;
|
package org.jivesoftware.smackx.jingle_filetransfer;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smackx.jingle.JingleManager;
|
||||||
import org.jivesoftware.smackx.jingle.Role;
|
import org.jivesoftware.smackx.jingle.Role;
|
||||||
import org.jivesoftware.smackx.jingle.element.Jingle;
|
import org.jivesoftware.smackx.jingle.element.Jingle;
|
||||||
|
|
||||||
|
@ -27,12 +28,17 @@ import org.jxmpp.jid.FullJid;
|
||||||
*/
|
*/
|
||||||
public class JingleFileRequest extends JingleFileTransferSession {
|
public class JingleFileRequest extends JingleFileTransferSession {
|
||||||
|
|
||||||
public JingleFileRequest(FullJid initiator, FullJid responder, Role role, String sid) {
|
public JingleFileRequest(XMPPConnection connection, FullJid initiator, FullJid responder, Role role, String sid) {
|
||||||
super(initiator, responder, role, sid, Type.request);
|
super(connection, initiator, responder, role, sid, Type.request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static JingleFileRequest createOutgoingFileRequest(XMPPConnection connection, FullJid recipient) {
|
||||||
public IQ handleJingleSessionRequest(Jingle jingle) {
|
return new JingleFileRequest(connection, connection.getUser().asFullJidOrThrow(), recipient, Role.initiator,
|
||||||
return null;
|
JingleManager.randomSid());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JingleFileRequest createIncomingFileRequest(XMPPConnection connection, Jingle request) {
|
||||||
|
return new JingleFileRequest(connection, request.getInitiator(), connection.getUser().asFullJidOrThrow(), Role.responder,
|
||||||
|
request.getSid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,11 @@ import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
import org.jivesoftware.smackx.jingle.JingleHandler;
|
import org.jivesoftware.smackx.jingle.JingleHandler;
|
||||||
import org.jivesoftware.smackx.jingle.JingleManager;
|
import org.jivesoftware.smackx.jingle.JingleManager;
|
||||||
import org.jivesoftware.smackx.jingle.Role;
|
import org.jivesoftware.smackx.jingle.JingleUtil;
|
||||||
import org.jivesoftware.smackx.jingle.element.Jingle;
|
import org.jivesoftware.smackx.jingle.element.Jingle;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleAction;
|
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_filetransfer.callback.IncomingFileOfferCallback;
|
||||||
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransfer;
|
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransfer;
|
||||||
|
|
||||||
import org.jxmpp.jid.FullJid;
|
import org.jxmpp.jid.FullJid;
|
||||||
|
@ -38,12 +39,14 @@ import org.jxmpp.jid.FullJid;
|
||||||
public final class JingleFileTransferManager extends Manager implements JingleHandler {
|
public final class JingleFileTransferManager extends Manager implements JingleHandler {
|
||||||
|
|
||||||
private static final WeakHashMap<XMPPConnection, JingleFileTransferManager> INSTANCES = new WeakHashMap<>();
|
private static final WeakHashMap<XMPPConnection, JingleFileTransferManager> INSTANCES = new WeakHashMap<>();
|
||||||
|
private final JingleUtil jutil;
|
||||||
|
|
||||||
private JingleFileTransferManager(XMPPConnection connection) {
|
private JingleFileTransferManager(XMPPConnection connection) {
|
||||||
super(connection);
|
super(connection);
|
||||||
ServiceDiscoveryManager.getInstanceFor(connection).addFeature(JingleFileTransfer.NAMESPACE_V5);
|
ServiceDiscoveryManager.getInstanceFor(connection).addFeature(JingleFileTransfer.NAMESPACE_V5);
|
||||||
JingleManager jingleManager = JingleManager.getInstanceFor(connection);
|
JingleManager jingleManager = JingleManager.getInstanceFor(connection);
|
||||||
jingleManager.registerDescriptionHandler(JingleFileTransfer.NAMESPACE_V5, this);
|
jingleManager.registerDescriptionHandler(JingleFileTransfer.NAMESPACE_V5, this);
|
||||||
|
jutil = new JingleUtil(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JingleFileTransferManager getInstanceFor(XMPPConnection connection) {
|
public static JingleFileTransferManager getInstanceFor(XMPPConnection connection) {
|
||||||
|
@ -60,22 +63,44 @@ public final class JingleFileTransferManager extends Manager implements JingleHa
|
||||||
FullJid fullJid = jingle.getFrom().asFullJidOrThrow();
|
FullJid fullJid = jingle.getFrom().asFullJidOrThrow();
|
||||||
String sid = jingle.getSid();
|
String sid = jingle.getSid();
|
||||||
|
|
||||||
JingleFileTransferSession handler = createSession(jingle);
|
//Get handler
|
||||||
|
JingleFileTransferSession handler;
|
||||||
|
try {
|
||||||
|
handler = createSessionHandler(jingle);
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
|
||||||
JingleManager.getInstanceFor(connection()).registerJingleSessionHandler(fullJid, sid, handler);
|
JingleManager.getInstanceFor(connection()).registerJingleSessionHandler(fullJid, sid, handler);
|
||||||
return handler.handleJingleSessionRequest(jingle);
|
return handler.handleJingleSessionRequest(jingle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private JingleFileTransferSession createSession(Jingle request) {
|
/**
|
||||||
|
* Create a session handler (FileOffer or FileRequest) for the request.
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private JingleFileTransferSession createSessionHandler(Jingle request) {
|
||||||
if (request.getAction() != JingleAction.session_initiate) {
|
if (request.getAction() != JingleAction.session_initiate) {
|
||||||
throw new IllegalArgumentException("Requests action MUST be session-initiate.");
|
throw new IllegalArgumentException("Requests action MUST be session-initiate.");
|
||||||
}
|
}
|
||||||
|
|
||||||
JingleContent content = request.getContents().get(0);
|
JingleContent content = request.getContents().get(0);
|
||||||
|
//File Offer
|
||||||
if (content.getSenders() == JingleContent.Senders.initiator) {
|
if (content.getSenders() == JingleContent.Senders.initiator) {
|
||||||
return new JingleFileOffer(request.getInitiator(), request.getResponder(), Role.responder, request.getSid());
|
return JingleFileOffer.createIncomingFileOffer(connection(), request);
|
||||||
} else if (content.getSenders() == JingleContent.Senders.responder) {
|
} //File Request
|
||||||
return new JingleFileRequest(request.getInitiator(), request.getResponder(), Role.responder, request.getSid());
|
else if (content.getSenders() == JingleContent.Senders.responder) {
|
||||||
} else {
|
return JingleFileRequest.createIncomingFileRequest(connection(), request);
|
||||||
|
} //Malformed Request
|
||||||
|
else {
|
||||||
throw new IllegalArgumentException("Requests content.senders MUST be either responder or initiator.");
|
throw new IllegalArgumentException("Requests content.senders MUST be either responder or initiator.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void notifyIncomingFileOffer(Jingle initiate, IncomingFileOfferCallback callback) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,9 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jingle_filetransfer;
|
package org.jivesoftware.smackx.jingle_filetransfer;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
import org.jivesoftware.smackx.jingle.JingleSession;
|
||||||
|
import org.jivesoftware.smackx.jingle.JingleUtil;
|
||||||
import org.jivesoftware.smackx.jingle.Role;
|
import org.jivesoftware.smackx.jingle.Role;
|
||||||
|
|
||||||
import org.jxmpp.jid.FullJid;
|
import org.jxmpp.jid.FullJid;
|
||||||
|
@ -33,23 +35,39 @@ public abstract class JingleFileTransferSession extends JingleSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
|
fresh,
|
||||||
pending,
|
pending,
|
||||||
active,
|
active,
|
||||||
terminated,
|
terminated,
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Type type;
|
protected final XMPPConnection connection;
|
||||||
|
protected final JingleUtil jutil;
|
||||||
|
|
||||||
public JingleFileTransferSession(FullJid initiator, FullJid responder, Role role, String sid, Type type) {
|
private final Type type;
|
||||||
|
private State state;
|
||||||
|
|
||||||
|
public JingleFileTransferSession(XMPPConnection connection, FullJid initiator, FullJid responder, Role role, String sid, Type type) {
|
||||||
super(initiator, responder, role, sid);
|
super(initiator, responder, role, sid);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.state = State.fresh;
|
||||||
|
this.connection = connection;
|
||||||
|
this.jutil = new JingleUtil(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getType() {
|
public Type getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(State state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isOffer() {
|
public boolean isOffer() {
|
||||||
return this.type == Type.offer;
|
return this.type == Type.offer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2017 Paul Schaub
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.jingle_filetransfer.callback;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransfer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback used to accept/decline file offers.
|
||||||
|
*/
|
||||||
|
public interface IncomingFileOfferCallback {
|
||||||
|
|
||||||
|
void accept(JingleFileTransfer file, File target);
|
||||||
|
|
||||||
|
void decline();
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2017 Paul Schaub
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.jingle_filetransfer.callback;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransfer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback used to accept/decline file requests.
|
||||||
|
*/
|
||||||
|
public interface IncomingFileRequestCallback {
|
||||||
|
|
||||||
|
void accept(JingleFileTransfer file, File source);
|
||||||
|
|
||||||
|
void decline();
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2017 Paul Schaub
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smack's API for <a href="https://xmpp.org/extensions/xep-0234.html">XEP-0234: Jingle File Transfer</a>.
|
||||||
|
* Callbacks.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.jingle_filetransfer.callback;
|
|
@ -27,6 +27,7 @@ import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
|
||||||
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.packet.IQ.Type;
|
import org.jivesoftware.smack.packet.IQ.Type;
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
import org.jivesoftware.smackx.jingle.element.Jingle;
|
import org.jivesoftware.smackx.jingle.element.Jingle;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleAction;
|
import org.jivesoftware.smackx.jingle.element.JingleAction;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContent;
|
import org.jivesoftware.smackx.jingle.element.JingleContent;
|
||||||
|
@ -73,7 +74,7 @@ public final class JingleManager extends Manager {
|
||||||
JingleSessionHandler sessionHandler = jingleSessionHandlers.get(fullJidAndSessionId);
|
JingleSessionHandler sessionHandler = jingleSessionHandlers.get(fullJidAndSessionId);
|
||||||
if (sessionHandler != null) {
|
if (sessionHandler != null) {
|
||||||
//Handle existing session
|
//Handle existing session
|
||||||
return sessionHandler.handleJingleSessionRequest(jingle, jingle.getSid());
|
return sessionHandler.handleJingleSessionRequest(jingle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jingle.getAction() == JingleAction.session_initiate) {
|
if (jingle.getAction() == JingleAction.session_initiate) {
|
||||||
|
@ -109,4 +110,8 @@ public final class JingleManager extends Manager {
|
||||||
FullJidAndSessionId fullJidAndSessionId = new FullJidAndSessionId(otherJid, sessionId);
|
FullJidAndSessionId fullJidAndSessionId = new FullJidAndSessionId(otherJid, sessionId);
|
||||||
return jingleSessionHandlers.remove(fullJidAndSessionId);
|
return jingleSessionHandlers.remove(fullJidAndSessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String randomSid() {
|
||||||
|
return StringUtils.randomString(24);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,6 +324,10 @@ public class JingleUtil {
|
||||||
return connection.createStanzaCollectorAndSend(jingle).nextResultOrThrow();
|
return connection.createStanzaCollectorAndSend(jingle).nextResultOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IQ sendContentRejectFileNotAvailable(FullJid recipient, String sessionId, JingleContentDescription description) {
|
||||||
|
return null; //TODO Later
|
||||||
|
}
|
||||||
|
|
||||||
public Jingle createSessionPing(FullJid recipient, String sessionId) {
|
public Jingle createSessionPing(FullJid recipient, String sessionId) {
|
||||||
Jingle.Builder jb = Jingle.getBuilder();
|
Jingle.Builder jb = Jingle.getBuilder();
|
||||||
jb.setSessionId(sessionId)
|
jb.setSessionId(sessionId)
|
||||||
|
@ -343,6 +347,14 @@ public class JingleUtil {
|
||||||
return connection.createStanzaCollectorAndSend(jingle).nextResultOrThrow();
|
return connection.createStanzaCollectorAndSend(jingle).nextResultOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IQ createAck(Jingle jingle) {
|
||||||
|
return IQ.createResultIQ(jingle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendAck(Jingle jingle) throws SmackException.NotConnectedException, InterruptedException {
|
||||||
|
connection.sendStanza(createAck(jingle));
|
||||||
|
}
|
||||||
|
|
||||||
public IQ createErrorUnknownSession(Jingle request) {
|
public IQ createErrorUnknownSession(Jingle request) {
|
||||||
XMPPError.Builder error = XMPPError.getBuilder();
|
XMPPError.Builder error = XMPPError.getBuilder();
|
||||||
error.setCondition(XMPPError.Condition.item_not_found)
|
error.setCondition(XMPPError.Condition.item_not_found)
|
||||||
|
@ -399,4 +411,13 @@ public class JingleUtil {
|
||||||
throws SmackException.NotConnectedException, InterruptedException {
|
throws SmackException.NotConnectedException, InterruptedException {
|
||||||
connection.sendStanza(createErrorOutOfOrder(request));
|
connection.sendStanza(createErrorOutOfOrder(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IQ createErrorMalformedRequest(Jingle request) {
|
||||||
|
return IQ.createErrorResponse(request, XMPPError.Condition.bad_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendErrorMalformedRequest(Jingle request)
|
||||||
|
throws SmackException.NotConnectedException, InterruptedException {
|
||||||
|
connection.sendStanza(createErrorMalformedRequest(request));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue