route jingle message inits
This commit is contained in:
parent
a4acfb2a19
commit
385692ea28
|
@ -39,7 +39,8 @@ public abstract class AbstractGenerator {
|
||||||
Namespace.JINGLE_TRANSPORT_ICE_UDP,
|
Namespace.JINGLE_TRANSPORT_ICE_UDP,
|
||||||
Namespace.JINGLE_FEATURE_AUDIO,
|
Namespace.JINGLE_FEATURE_AUDIO,
|
||||||
Namespace.JINGLE_FEATURE_VIDEO,
|
Namespace.JINGLE_FEATURE_VIDEO,
|
||||||
Namespace.JINGLE_APP_RTP,
|
Namespace.JINGLE_APPS_RTP,
|
||||||
|
Namespace.JINGLE_APPS_DTLS,
|
||||||
|
|
||||||
"http://jabber.org/protocol/muc",
|
"http://jabber.org/protocol/muc",
|
||||||
"jabber:x:conference",
|
"jabber:x:conference",
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.util.Pair;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -50,6 +51,8 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
|
|
||||||
private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH);
|
private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH);
|
||||||
|
|
||||||
|
private static final List<String> JINGLE_MESSAGE_ELEMENT_NAMES = Arrays.asList("accept", "propose", "proceed", "reject", "retract");
|
||||||
|
|
||||||
public MessageParser(XmppConnectionService service) {
|
public MessageParser(XmppConnectionService service) {
|
||||||
super(service);
|
super(service);
|
||||||
}
|
}
|
||||||
|
@ -136,7 +139,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
return new Message(conversation, "", Message.ENCRYPTION_AXOLOTL_FAILED, status);
|
return new Message(conversation, "", Message.ENCRYPTION_AXOLOTL_FAILED, status);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG,"ignoring broken session exception because checkForDuplicates failed");
|
Log.d(Config.LOGTAG, "ignoring broken session exception because checkForDuplicates failed");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (NotEncryptedForThisDeviceException e) {
|
} catch (NotEncryptedForThisDeviceException e) {
|
||||||
|
@ -249,13 +252,13 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
final Jid id = InvalidJid.getNullForInvalid(retract.getAttributeAsJid("id"));
|
final Jid id = InvalidJid.getNullForInvalid(retract.getAttributeAsJid("id"));
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
account.removeBookmark(id);
|
account.removeBookmark(id);
|
||||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": deleted bookmark for "+id);
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": deleted bookmark for " + id);
|
||||||
mXmppConnectionService.processDeletedBookmark(account, id);
|
mXmppConnectionService.processDeletedBookmark(account, id);
|
||||||
mXmppConnectionService.updateConversationUi();
|
mXmppConnectionService.updateConversationUi();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+" received pubsub notification for node="+node);
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + " received pubsub notification for node=" + node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +270,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
setNick(account, from, null);
|
setNick(account, from, null);
|
||||||
} else if (Namespace.BOOKMARKS2.equals(node) && account.getJid().asBareJid().equals(from)) {
|
} else if (Namespace.BOOKMARKS2.equals(node) && account.getJid().asBareJid().equals(from)) {
|
||||||
account.setBookmarks(Collections.emptyMap());
|
account.setBookmarks(Collections.emptyMap());
|
||||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": deleted bookmarks node");
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": deleted bookmarks node");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +279,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
final String node = purge == null ? null : purge.getAttribute("node");
|
final String node = purge == null ? null : purge.getAttribute("node");
|
||||||
if (Namespace.BOOKMARKS2.equals(node) && account.getJid().asBareJid().equals(from)) {
|
if (Namespace.BOOKMARKS2.equals(node) && account.getJid().asBareJid().equals(from)) {
|
||||||
account.setBookmarks(Collections.emptyMap());
|
account.setBookmarks(Collections.emptyMap());
|
||||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": purged bookmarks");
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": purged bookmarks");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,10 +311,10 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
final Element error = packet.findChild("error");
|
final Element error = packet.findChild("error");
|
||||||
final boolean pingWorthyError = error != null && (error.hasChild("not-acceptable") || error.hasChild("remote-server-timeout") || error.hasChild("remote-server-not-found"));
|
final boolean pingWorthyError = error != null && (error.hasChild("not-acceptable") || error.hasChild("remote-server-timeout") || error.hasChild("remote-server-not-found"));
|
||||||
if (pingWorthyError) {
|
if (pingWorthyError) {
|
||||||
Conversation conversation = mXmppConnectionService.find(account,from);
|
Conversation conversation = mXmppConnectionService.find(account, from);
|
||||||
if (conversation != null && conversation.getMode() == Conversational.MODE_MULTI) {
|
if (conversation != null && conversation.getMode() == Conversational.MODE_MULTI) {
|
||||||
if (conversation.getMucOptions().online()) {
|
if (conversation.getMucOptions().online()) {
|
||||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": received ping worthy error for seemingly online muc at "+from);
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received ping worthy error for seemingly online muc at " + from);
|
||||||
mXmppConnectionService.mucSelfPingAndRejoin(conversation);
|
mXmppConnectionService.mucSelfPingAndRejoin(conversation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,9 +422,9 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
final Invite invite = extractInvite(packet);
|
final Invite invite = extractInvite(packet);
|
||||||
if (invite != null) {
|
if (invite != null) {
|
||||||
if (isTypeGroupChat) {
|
if (isTypeGroupChat) {
|
||||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": ignoring invite to "+invite.jid+" because type=groupchat");
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": ignoring invite to " + invite.jid + " because type=groupchat");
|
||||||
} else if (invite.direct && (mucUserElement != null || invite.inviter == null || mXmppConnectionService.isMuc(account, invite.inviter))) {
|
} else if (invite.direct && (mucUserElement != null || invite.inviter == null || mXmppConnectionService.isMuc(account, invite.inviter))) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid()+": ignoring direct invite to "+invite.jid+" because it was received in MUC");
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": ignoring direct invite to " + invite.jid + " because it was received in MUC");
|
||||||
} else {
|
} else {
|
||||||
invite.execute(account);
|
invite.execute(account);
|
||||||
return;
|
return;
|
||||||
|
@ -504,7 +507,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
final boolean checkedForDuplicates = liveMessage || (serverMsgId != null && remoteMsgId != null && !conversation.possibleDuplicate(serverMsgId, remoteMsgId));
|
final boolean checkedForDuplicates = liveMessage || (serverMsgId != null && remoteMsgId != null && !conversation.possibleDuplicate(serverMsgId, remoteMsgId));
|
||||||
|
|
||||||
if (origin != null) {
|
if (origin != null) {
|
||||||
message = parseAxolotlChat(axolotlEncrypted, origin, conversation, status, checkedForDuplicates,query != null);
|
message = parseAxolotlChat(axolotlEncrypted, origin, conversation, status, checkedForDuplicates, query != null);
|
||||||
} else {
|
} else {
|
||||||
Message trial = null;
|
Message trial = null;
|
||||||
for (Jid fallback : fallbacksBySourceId) {
|
for (Jid fallback : fallbacksBySourceId) {
|
||||||
|
@ -809,6 +812,13 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!isTypeGroupChat) {
|
||||||
|
for (Element child : packet.getChildren()) {
|
||||||
|
if (Namespace.JINGLE_MESSAGE.equals(child.getNamespace()) && JINGLE_MESSAGE_ELEMENT_NAMES.contains(child.getName())) {
|
||||||
|
mXmppConnectionService.getJingleConnectionManager().deliverMessage(account, packet.getTo(), packet.getFrom(), child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Element received = packet.findChild("received", "urn:xmpp:chat-markers:0");
|
Element received = packet.findChild("received", "urn:xmpp:chat-markers:0");
|
||||||
|
@ -944,7 +954,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
||||||
if (jid != null) {
|
if (jid != null) {
|
||||||
Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, jid, true, false);
|
Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, jid, true, false);
|
||||||
if (conversation.getMucOptions().online()) {
|
if (conversation.getMucOptions().online()) {
|
||||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": received invite to "+jid+" but muc is considered to be online");
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received invite to " + jid + " but muc is considered to be online");
|
||||||
mXmppConnectionService.mucSelfPingAndRejoin(conversation);
|
mXmppConnectionService.mucSelfPingAndRejoin(conversation);
|
||||||
} else {
|
} else {
|
||||||
conversation.getMucOptions().setPassword(password);
|
conversation.getMucOptions().setPassword(password);
|
||||||
|
|
|
@ -16,9 +16,9 @@ public final class Namespace {
|
||||||
public static final String SASL = "urn:ietf:params:xml:ns:xmpp-sasl";
|
public static final String SASL = "urn:ietf:params:xml:ns:xmpp-sasl";
|
||||||
public static final String TLS = "urn:ietf:params:xml:ns:xmpp-tls";
|
public static final String TLS = "urn:ietf:params:xml:ns:xmpp-tls";
|
||||||
public static final String PUBSUB = "http://jabber.org/protocol/pubsub";
|
public static final String PUBSUB = "http://jabber.org/protocol/pubsub";
|
||||||
public static final String PUBSUB_PUBLISH_OPTIONS = PUBSUB+"#publish-options";
|
public static final String PUBSUB_PUBLISH_OPTIONS = PUBSUB + "#publish-options";
|
||||||
public static final String PUBSUB_ERROR = PUBSUB+"#errors";
|
public static final String PUBSUB_ERROR = PUBSUB + "#errors";
|
||||||
public static final String PUBSUB_OWNER = PUBSUB+"#owner";
|
public static final String PUBSUB_OWNER = PUBSUB + "#owner";
|
||||||
public static final String NICK = "http://jabber.org/protocol/nick";
|
public static final String NICK = "http://jabber.org/protocol/nick";
|
||||||
public static final String FLEXIBLE_OFFLINE_MESSAGE_RETRIEVAL = "http://jabber.org/protocol/offline";
|
public static final String FLEXIBLE_OFFLINE_MESSAGE_RETRIEVAL = "http://jabber.org/protocol/offline";
|
||||||
public static final String BIND = "urn:ietf:params:xml:ns:xmpp-bind";
|
public static final String BIND = "urn:ietf:params:xml:ns:xmpp-bind";
|
||||||
|
@ -27,22 +27,24 @@ public final class Namespace {
|
||||||
public static final String BOOKMARKS = "storage:bookmarks";
|
public static final String BOOKMARKS = "storage:bookmarks";
|
||||||
public static final String SYNCHRONIZATION = "im.quicksy.synchronization:0";
|
public static final String SYNCHRONIZATION = "im.quicksy.synchronization:0";
|
||||||
public static final String AVATAR_CONVERSION = "urn:xmpp:pep-vcard-conversion:0";
|
public static final String AVATAR_CONVERSION = "urn:xmpp:pep-vcard-conversion:0";
|
||||||
|
public static final String JINGLE = "urn:xmpp:jingle:1";
|
||||||
|
public static final String JINGLE_MESSAGE = "urn:xmpp:jingle-message:0";
|
||||||
|
public static final String JINGLE_ENCRYPTED_TRANSPORT = "urn:xmpp:jingle:jet:0";
|
||||||
|
public static final String JINGLE_ENCRYPTED_TRANSPORT_OMEMO = "urn:xmpp:jingle:jet-omemo:0";
|
||||||
public static final String JINGLE_TRANSPORTS_S5B = "urn:xmpp:jingle:transports:s5b:1";
|
public static final String JINGLE_TRANSPORTS_S5B = "urn:xmpp:jingle:transports:s5b:1";
|
||||||
public static final String JINGLE_TRANSPORTS_IBB = "urn:xmpp:jingle:transports:ibb:1";
|
public static final String JINGLE_TRANSPORTS_IBB = "urn:xmpp:jingle:transports:ibb:1";
|
||||||
public static final String JINGLE_TRANSPORT_ICE_UDP = "urn:xmpp:jingle:transports:ice-udp:1";
|
public static final String JINGLE_TRANSPORT_ICE_UDP = "urn:xmpp:jingle:transports:ice-udp:1";
|
||||||
public static final String JINGLE_APP_RTP = "urn:xmpp:jingle:apps:rtp:1";
|
public static final String JINGLE_APPS_RTP = "urn:xmpp:jingle:apps:rtp:1";
|
||||||
|
public static final String JINGLE_APPS_DTLS = "urn:xmpp:jingle:apps:dtls:0";
|
||||||
public static final String JINGLE_FEATURE_AUDIO = "urn:xmpp:jingle:apps:rtp:audio";
|
public static final String JINGLE_FEATURE_AUDIO = "urn:xmpp:jingle:apps:rtp:audio";
|
||||||
public static final String JINGLE_FEATURE_VIDEO = "urn:xmpp:jingle:apps:rtp:video";
|
public static final String JINGLE_FEATURE_VIDEO = "urn:xmpp:jingle:apps:rtp:video";
|
||||||
public static final String IBB = "http://jabber.org/protocol/ibb";
|
public static final String IBB = "http://jabber.org/protocol/ibb";
|
||||||
public static final String PING = "urn:xmpp:ping";
|
public static final String PING = "urn:xmpp:ping";
|
||||||
public static final String PUSH = "urn:xmpp:push:0";
|
public static final String PUSH = "urn:xmpp:push:0";
|
||||||
public static final String COMMANDS = "http://jabber.org/protocol/commands";
|
public static final String COMMANDS = "http://jabber.org/protocol/commands";
|
||||||
public static final String JINGLE = "urn:xmpp:jingle:1";
|
|
||||||
public static final String JINGLE_ENCRYPTED_TRANSPORT = "urn:xmpp:jingle:jet:0";
|
|
||||||
public static final String JINGLE_ENCRYPTED_TRANSPORT_OMEMO = "urn:xmpp:jingle:jet-omemo:0";
|
|
||||||
public static final String MUC_USER = "http://jabber.org/protocol/muc#user";
|
public static final String MUC_USER = "http://jabber.org/protocol/muc#user";
|
||||||
public static final String BOOKMARKS2 = "urn:xmpp:bookmarks:0";
|
public static final String BOOKMARKS2 = "urn:xmpp:bookmarks:0";
|
||||||
public static final String BOOKMARKS2_COMPAT = BOOKMARKS2+"#compat";
|
public static final String BOOKMARKS2_COMPAT = BOOKMARKS2 + "#compat";
|
||||||
public static final String INVITE = "urn:xmpp:invite";
|
public static final String INVITE = "urn:xmpp:invite";
|
||||||
public static final String PARS = "urn:xmpp:pars:0";
|
public static final String PARS = "urn:xmpp:pars:0";
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,14 +30,14 @@ public abstract class AbstractJingleConnection {
|
||||||
|
|
||||||
public static class Id {
|
public static class Id {
|
||||||
public final Account account;
|
public final Account account;
|
||||||
public final Jid counterPart;
|
public final Jid with;
|
||||||
public final String sessionId;
|
public final String sessionId;
|
||||||
|
|
||||||
private Id(final Account account, final Jid counterPart, final String sessionId) {
|
private Id(final Account account, final Jid with, final String sessionId) {
|
||||||
Preconditions.checkNotNull(counterPart);
|
Preconditions.checkNotNull(with);
|
||||||
Preconditions.checkArgument(counterPart.isFullJid());
|
Preconditions.checkArgument(with.isFullJid());
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.counterPart = counterPart;
|
this.with = with;
|
||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,10 @@ public abstract class AbstractJingleConnection {
|
||||||
return new Id(account, jinglePacket.getFrom(), jinglePacket.getSessionId());
|
return new Id(account, jinglePacket.getFrom(), jinglePacket.getSessionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Id of(Account account, Jid with, final String sessionId) {
|
||||||
|
return new Id(account, with, sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
public static Id of(Message message) {
|
public static Id of(Message message) {
|
||||||
return new Id(
|
return new Id(
|
||||||
message.getConversation().getAccount(),
|
message.getConversation().getAccount(),
|
||||||
|
@ -59,13 +63,13 @@ public abstract class AbstractJingleConnection {
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
Id id = (Id) o;
|
Id id = (Id) o;
|
||||||
return Objects.equal(account.getJid(), id.account.getJid()) &&
|
return Objects.equal(account.getJid(), id.account.getJid()) &&
|
||||||
Objects.equal(counterPart, id.counterPart) &&
|
Objects.equal(with, id.with) &&
|
||||||
Objects.equal(sessionId, id.sessionId);
|
Objects.equal(sessionId, id.sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(account.getJid(), counterPart, sessionId);
|
return Objects.hashCode(account.getJid(), with, sessionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import eu.siacs.conversations.xmpp.jingle.stanzas.Content;
|
||||||
import eu.siacs.conversations.xmpp.jingle.stanzas.FileTransferDescription;
|
import eu.siacs.conversations.xmpp.jingle.stanzas.FileTransferDescription;
|
||||||
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
|
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
|
||||||
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
||||||
|
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
|
||||||
import rocks.xmpp.addr.Jid;
|
import rocks.xmpp.addr.Jid;
|
||||||
|
|
||||||
public class JingleConnectionManager extends AbstractConnectionManager {
|
public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
|
@ -35,13 +36,16 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
|
|
||||||
public void deliverPacket(final Account account, final JinglePacket packet) {
|
public void deliverPacket(final Account account, final JinglePacket packet) {
|
||||||
final AbstractJingleConnection.Id id = AbstractJingleConnection.Id.of(account, packet);
|
final AbstractJingleConnection.Id id = AbstractJingleConnection.Id.of(account, packet);
|
||||||
if (packet.getAction() == JinglePacket.Action.SESSION_INITIATE) { //TODO check that id doesn't exist yet
|
final AbstractJingleConnection existingJingleConnection = connections.get(id);
|
||||||
|
if (existingJingleConnection != null) {
|
||||||
|
existingJingleConnection.deliverPacket(packet);
|
||||||
|
} else if (packet.getAction() == JinglePacket.Action.SESSION_INITIATE) {
|
||||||
final Content content = packet.getJingleContent();
|
final Content content = packet.getJingleContent();
|
||||||
final String descriptionNamespace = content == null ? null : content.getDescriptionNamespace();
|
final String descriptionNamespace = content == null ? null : content.getDescriptionNamespace();
|
||||||
final AbstractJingleConnection connection;
|
final AbstractJingleConnection connection;
|
||||||
if (FileTransferDescription.NAMESPACES.contains(descriptionNamespace)) {
|
if (FileTransferDescription.NAMESPACES.contains(descriptionNamespace)) {
|
||||||
connection = new JingleFileTransferConnection(this, id);
|
connection = new JingleFileTransferConnection(this, id);
|
||||||
} else if (Namespace.JINGLE_APP_RTP.equals(descriptionNamespace)) {
|
} else if (Namespace.JINGLE_APPS_RTP.equals(descriptionNamespace)) {
|
||||||
connection = new JingleRtpConnection(this, id);
|
connection = new JingleRtpConnection(this, id);
|
||||||
} else {
|
} else {
|
||||||
//TODO return feature-not-implemented
|
//TODO return feature-not-implemented
|
||||||
|
@ -49,21 +53,52 @@ public class JingleConnectionManager extends AbstractConnectionManager {
|
||||||
}
|
}
|
||||||
connections.put(id, connection);
|
connections.put(id, connection);
|
||||||
connection.deliverPacket(packet);
|
connection.deliverPacket(packet);
|
||||||
} else {
|
|
||||||
final AbstractJingleConnection abstractJingleConnection = connections.get(id);
|
|
||||||
if (abstractJingleConnection != null) {
|
|
||||||
abstractJingleConnection.deliverPacket(packet);
|
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG, "unable to route jingle packet: " + packet);
|
Log.d(Config.LOGTAG, "unable to route jingle packet: " + packet);
|
||||||
IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR);
|
final IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR);
|
||||||
Element error = response.addChild("error");
|
final Element error = response.addChild("error");
|
||||||
error.setAttribute("type", "cancel");
|
error.setAttribute("type", "cancel");
|
||||||
error.addChild("item-not-found",
|
error.addChild("item-not-found", "urn:ietf:params:xml:ns:xmpp-stanzas");
|
||||||
"urn:ietf:params:xml:ns:xmpp-stanzas");
|
|
||||||
error.addChild("unknown-session", "urn:xmpp:jingle:errors:1");
|
error.addChild("unknown-session", "urn:xmpp:jingle:errors:1");
|
||||||
account.getXmppConnection().sendIqPacket(response, null);
|
account.getXmppConnection().sendIqPacket(response, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deliverMessage(final Account account, final Jid to, final Jid from, final Element message) {
|
||||||
|
Preconditions.checkArgument(Namespace.JINGLE_MESSAGE.equals(message.getNamespace()));
|
||||||
|
final String sessionId = message.getAttribute("id");
|
||||||
|
if (sessionId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Jid with;
|
||||||
|
if (account.getJid().asBareJid().equals(from.asBareJid())) {
|
||||||
|
with = to;
|
||||||
|
} else {
|
||||||
|
with = from;
|
||||||
|
}
|
||||||
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received jingle message from " + from + " with=" + with + " " + message);
|
||||||
|
final AbstractJingleConnection.Id id = AbstractJingleConnection.Id.of(account, with, sessionId);
|
||||||
|
final AbstractJingleConnection existingJingleConnection = connections.get(id);
|
||||||
|
if (existingJingleConnection != null) {
|
||||||
|
if (existingJingleConnection instanceof JingleRtpConnection) {
|
||||||
|
((JingleRtpConnection) existingJingleConnection).deliveryMessage(to, from, message);
|
||||||
|
} else {
|
||||||
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": " + existingJingleConnection.getClass().getName() + " does not support jingle messages");
|
||||||
|
}
|
||||||
|
} else if ("propose".equals(message.getName())) {
|
||||||
|
final Element description = message.findChild("description");
|
||||||
|
final String namespace = description == null ? null : description.getNamespace();
|
||||||
|
if (Namespace.JINGLE_APPS_RTP.equals(namespace)) {
|
||||||
|
final JingleRtpConnection rtpConnection = new JingleRtpConnection(this, id);
|
||||||
|
this.connections.put(id, rtpConnection);
|
||||||
|
rtpConnection.deliveryMessage(to, from, message);
|
||||||
|
} else {
|
||||||
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to react to proposed " + namespace + " session");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": retrieved out of order jingle message");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startJingleFileTransfer(final Message message) {
|
public void startJingleFileTransfer(final Message message) {
|
||||||
|
|
|
@ -4,11 +4,7 @@ import android.util.Base64;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
@ -351,7 +347,7 @@ public class JingleFileTransferConnection extends AbstractJingleConnection imple
|
||||||
this.message.setTransferable(this);
|
this.message.setTransferable(this);
|
||||||
this.mStatus = Transferable.STATUS_UPLOADING;
|
this.mStatus = Transferable.STATUS_UPLOADING;
|
||||||
this.initiator = this.id.account.getJid();
|
this.initiator = this.id.account.getJid();
|
||||||
this.responder = this.id.counterPart;
|
this.responder = this.id.with;
|
||||||
this.transportId = JingleConnectionManager.nextRandomId();
|
this.transportId = JingleConnectionManager.nextRandomId();
|
||||||
this.setupDescription(remoteVersion);
|
this.setupDescription(remoteVersion);
|
||||||
if (this.initialTransport == IbbTransportInfo.class) {
|
if (this.initialTransport == IbbTransportInfo.class) {
|
||||||
|
@ -416,7 +412,7 @@ public class JingleFileTransferConnection extends AbstractJingleConnection imple
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getRemoteFeatures() {
|
private List<String> getRemoteFeatures() {
|
||||||
final Jid jid = this.id.counterPart;
|
final Jid jid = this.id.with;
|
||||||
String resource = jid != null ? jid.getResource() : null;
|
String resource = jid != null ? jid.getResource() : null;
|
||||||
if (resource != null) {
|
if (resource != null) {
|
||||||
Presence presence = this.id.account.getRoster().getContact(jid).getPresences().getPresences().get(resource);
|
Presence presence = this.id.account.getRoster().getContact(jid).getPresences().getPresences().get(resource);
|
||||||
|
@ -428,14 +424,15 @@ public class JingleFileTransferConnection extends AbstractJingleConnection imple
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init(JinglePacket packet) { //should move to deliverPacket
|
private void init(JinglePacket packet) { //should move to deliverPacket
|
||||||
|
//TODO if not 'OFFERED' reply with out-of-order
|
||||||
this.mJingleStatus = JINGLE_STATUS_INITIATED;
|
this.mJingleStatus = JINGLE_STATUS_INITIATED;
|
||||||
final Conversation conversation = this.xmppConnectionService.findOrCreateConversation(id.account, id.counterPart.asBareJid(), false, false);
|
final Conversation conversation = this.xmppConnectionService.findOrCreateConversation(id.account, id.with.asBareJid(), false, false);
|
||||||
this.message = new Message(conversation, "", Message.ENCRYPTION_NONE);
|
this.message = new Message(conversation, "", Message.ENCRYPTION_NONE);
|
||||||
this.message.setStatus(Message.STATUS_RECEIVED);
|
this.message.setStatus(Message.STATUS_RECEIVED);
|
||||||
this.mStatus = Transferable.STATUS_OFFER;
|
this.mStatus = Transferable.STATUS_OFFER;
|
||||||
this.message.setTransferable(this);
|
this.message.setTransferable(this);
|
||||||
this.message.setCounterpart(this.id.counterPart);
|
this.message.setCounterpart(this.id.with);
|
||||||
this.initiator = this.id.counterPart;
|
this.initiator = this.id.with;
|
||||||
this.responder = this.id.account.getJid();
|
this.responder = this.id.account.getJid();
|
||||||
final Content content = packet.getJingleContent();
|
final Content content = packet.getJingleContent();
|
||||||
final GenericTransportInfo transportInfo = content.getTransport();
|
final GenericTransportInfo transportInfo = content.getTransport();
|
||||||
|
@ -527,11 +524,11 @@ public class JingleFileTransferConnection extends AbstractJingleConnection imple
|
||||||
|
|
||||||
respondToIq(packet, true);
|
respondToIq(packet, true);
|
||||||
|
|
||||||
if (id.account.getRoster().getContact(id.counterPart).showInContactList()
|
if (id.account.getRoster().getContact(id.with).showInContactList()
|
||||||
&& jingleConnectionManager.hasStoragePermission()
|
&& jingleConnectionManager.hasStoragePermission()
|
||||||
&& size < this.jingleConnectionManager.getAutoAcceptFileSize()
|
&& size < this.jingleConnectionManager.getAutoAcceptFileSize()
|
||||||
&& xmppConnectionService.isDataSaverDisabled()) {
|
&& xmppConnectionService.isDataSaverDisabled()) {
|
||||||
Log.d(Config.LOGTAG, "auto accepting file from " + id.counterPart);
|
Log.d(Config.LOGTAG, "auto accepting file from " + id.with);
|
||||||
this.acceptedAutomatically = true;
|
this.acceptedAutomatically = true;
|
||||||
this.sendAccept();
|
this.sendAccept();
|
||||||
} else {
|
} else {
|
||||||
|
@ -697,7 +694,7 @@ public class JingleFileTransferConnection extends AbstractJingleConnection imple
|
||||||
|
|
||||||
private JinglePacket bootstrapPacket(JinglePacket.Action action) {
|
private JinglePacket bootstrapPacket(JinglePacket.Action action) {
|
||||||
final JinglePacket packet = new JinglePacket(action, this.id.sessionId);
|
final JinglePacket packet = new JinglePacket(action, this.id.sessionId);
|
||||||
packet.setTo(id.counterPart);
|
packet.setTo(id.with);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,7 +834,7 @@ public class JingleFileTransferConnection extends AbstractJingleConnection imple
|
||||||
activation.query("http://jabber.org/protocol/bytestreams")
|
activation.query("http://jabber.org/protocol/bytestreams")
|
||||||
.setAttribute("sid", sid);
|
.setAttribute("sid", sid);
|
||||||
activation.query().addChild("activate")
|
activation.query().addChild("activate")
|
||||||
.setContent(this.id.counterPart.toEscapedString());
|
.setContent(this.id.with.toEscapedString());
|
||||||
xmppConnectionService.sendIqPacket(this.id.account, activation, (account, response) -> {
|
xmppConnectionService.sendIqPacket(this.id.account, activation, (account, response) -> {
|
||||||
if (response.getType() != IqPacket.TYPE.RESULT) {
|
if (response.getType() != IqPacket.TYPE.RESULT) {
|
||||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": " + response.toString());
|
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": " + response.toString());
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class JingleInBandTransport extends JingleTransport {
|
||||||
JingleInBandTransport(final JingleFileTransferConnection connection, final String sid, final int blockSize) {
|
JingleInBandTransport(final JingleFileTransferConnection connection, final String sid, final int blockSize) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.account = connection.getId().account;
|
this.account = connection.getId().account;
|
||||||
this.counterpart = connection.getId().counterPart;
|
this.counterpart = connection.getId().with;
|
||||||
this.blockSize = blockSize;
|
this.blockSize = blockSize;
|
||||||
this.sessionId = sid;
|
this.sessionId = sid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,9 @@ package eu.siacs.conversations.xmpp.jingle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
|
import eu.siacs.conversations.xml.Element;
|
||||||
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
|
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
|
||||||
|
import rocks.xmpp.addr.Jid;
|
||||||
|
|
||||||
public class JingleRtpConnection extends AbstractJingleConnection {
|
public class JingleRtpConnection extends AbstractJingleConnection {
|
||||||
|
|
||||||
|
@ -16,4 +18,8 @@ public class JingleRtpConnection extends AbstractJingleConnection {
|
||||||
void deliverPacket(final JinglePacket jinglePacket) {
|
void deliverPacket(final JinglePacket jinglePacket) {
|
||||||
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": packet delivered to JingleRtpConnection");
|
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": packet delivered to JingleRtpConnection");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void deliveryMessage(final Jid to, Jid from, Element message) {
|
||||||
|
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": delivered message to JingleRtpConnection " + message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import eu.siacs.conversations.services.AbstractConnectionManager;
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
import eu.siacs.conversations.utils.CryptoHelper;
|
||||||
import eu.siacs.conversations.utils.SocksSocketFactory;
|
import eu.siacs.conversations.utils.SocksSocketFactory;
|
||||||
import eu.siacs.conversations.utils.WakeLockHelper;
|
import eu.siacs.conversations.utils.WakeLockHelper;
|
||||||
import eu.siacs.conversations.xmpp.jingle.stanzas.Content;
|
|
||||||
import eu.siacs.conversations.xmpp.jingle.stanzas.FileTransferDescription;
|
import eu.siacs.conversations.xmpp.jingle.stanzas.FileTransferDescription;
|
||||||
|
|
||||||
public class JingleSocks5Transport extends JingleTransport {
|
public class JingleSocks5Transport extends JingleTransport {
|
||||||
|
@ -61,9 +60,9 @@ public class JingleSocks5Transport extends JingleTransport {
|
||||||
}
|
}
|
||||||
if (candidate.isOurs()) {
|
if (candidate.isOurs()) {
|
||||||
destBuilder.append(this.account.getJid());
|
destBuilder.append(this.account.getJid());
|
||||||
destBuilder.append(this.connection.getId().counterPart);
|
destBuilder.append(this.connection.getId().with);
|
||||||
} else {
|
} else {
|
||||||
destBuilder.append(this.connection.getId().counterPart);
|
destBuilder.append(this.connection.getId().with);
|
||||||
destBuilder.append(this.account.getJid());
|
destBuilder.append(this.account.getJid());
|
||||||
}
|
}
|
||||||
messageDigest.reset();
|
messageDigest.reset();
|
||||||
|
|
|
@ -14,8 +14,8 @@ public class RtpDescription extends GenericDescription {
|
||||||
|
|
||||||
public static RtpDescription upgrade(final Element element) {
|
public static RtpDescription upgrade(final Element element) {
|
||||||
Preconditions.checkArgument("description".equals(element.getName()), "Name of provided element is not description");
|
Preconditions.checkArgument("description".equals(element.getName()), "Name of provided element is not description");
|
||||||
Preconditions.checkArgument(Namespace.JINGLE_APP_RTP.equals(element.getNamespace()), "Element does not match the jingle rtp namespace");
|
Preconditions.checkArgument(Namespace.JINGLE_APPS_RTP.equals(element.getNamespace()), "Element does not match the jingle rtp namespace");
|
||||||
final RtpDescription description = new RtpDescription("description", Namespace.JINGLE_APP_RTP);
|
final RtpDescription description = new RtpDescription("description", Namespace.JINGLE_APPS_RTP);
|
||||||
description.setAttributes(element.getAttributes());
|
description.setAttributes(element.getAttributes());
|
||||||
description.setChildren(element.getChildren());
|
description.setChildren(element.getChildren());
|
||||||
return description;
|
return description;
|
||||||
|
|
Loading…
Reference in New Issue