aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus/xmpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/xmpp')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/OnAdvancedStreamFeaturesLoaded.java7
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/OnBindListener.java7
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/OnContactStatusChanged.java7
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/OnIqPacketReceived.java8
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/OnMessageAcknowledged.java7
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/OnMessagePacketReceived.java8
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/OnPresencePacketReceived.java8
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/OnStatusChanged.java7
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/OnUpdateBlocklist.java13
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/PacketReceived.java5
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java1164
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/avatar/AvatarPacketGenerator.java9
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/avatar/AvatarPacketParser.java5
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/chatstate/ChatState.java32
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/forms/Data.java85
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/forms/Field.java50
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jid/InvalidJidException.java49
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jid/Jid.java226
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleCandidate.java147
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java960
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java171
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleInbandTransport.java243
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleSocks5Transport.java246
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleTransport.java15
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnFileTransmissionStatusChanged.java9
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnJinglePacketReceived.java9
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnPrimaryCandidateFound.java6
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnTransportConnected.java7
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/stanzas/Content.java102
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/stanzas/JinglePacket.java96
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/stanzas/Reason.java13
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/pep/Avatar.java102
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacket.java4
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacketGenerator.java4
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacketParser.java4
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/AbstractStanza.java58
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacket.java63
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketGenerator.java2
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/MessagePacket.java96
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/PresencePacket.java8
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/ActivePacket.java10
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/InactivePacket.java10
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/AckPacket.java13
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/EnablePacket.java13
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/RequestPacket.java12
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/ResumePacket.java14
46 files changed, 16 insertions, 4118 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnAdvancedStreamFeaturesLoaded.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/OnAdvancedStreamFeaturesLoaded.java
deleted file mode 100644
index 0692232c..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnAdvancedStreamFeaturesLoaded.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp;
-
-import de.thedevstack.conversationsplus.entities.Account;
-
-public interface OnAdvancedStreamFeaturesLoaded {
- public void onAdvancedStreamFeaturesAvailable(final Account account);
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnBindListener.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/OnBindListener.java
deleted file mode 100644
index 274511e0..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnBindListener.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp;
-
-import de.thedevstack.conversationsplus.entities.Account;
-
-public interface OnBindListener {
- public void onBind(Account account);
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnContactStatusChanged.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/OnContactStatusChanged.java
deleted file mode 100644
index 009b33df..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnContactStatusChanged.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp;
-
-import de.thedevstack.conversationsplus.entities.Contact;
-
-public interface OnContactStatusChanged {
- public void onContactStatusChanged(final Contact contact, final boolean online);
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnIqPacketReceived.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/OnIqPacketReceived.java
deleted file mode 100644
index df0178c6..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnIqPacketReceived.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp;
-
-import de.thedevstack.conversationsplus.entities.Account;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
-
-public interface OnIqPacketReceived extends PacketReceived {
- public void onIqPacketReceived(Account account, IqPacket packet);
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnMessageAcknowledged.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/OnMessageAcknowledged.java
deleted file mode 100644
index 7cfa557d..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnMessageAcknowledged.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp;
-
-import de.thedevstack.conversationsplus.entities.Account;
-
-public interface OnMessageAcknowledged {
- public void onMessageAcknowledged(Account account, String id);
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnMessagePacketReceived.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/OnMessagePacketReceived.java
deleted file mode 100644
index 47649a18..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnMessagePacketReceived.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp;
-
-import de.thedevstack.conversationsplus.entities.Account;
-import de.thedevstack.conversationsplus.xmpp.stanzas.MessagePacket;
-
-public interface OnMessagePacketReceived extends PacketReceived {
- public void onMessagePacketReceived(Account account, MessagePacket packet);
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnPresencePacketReceived.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/OnPresencePacketReceived.java
deleted file mode 100644
index 70b0ccd2..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnPresencePacketReceived.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp;
-
-import de.thedevstack.conversationsplus.entities.Account;
-import de.thedevstack.conversationsplus.xmpp.stanzas.PresencePacket;
-
-public interface OnPresencePacketReceived extends PacketReceived {
- public void onPresencePacketReceived(Account account, PresencePacket packet);
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnStatusChanged.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/OnStatusChanged.java
deleted file mode 100644
index c8478bbb..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnStatusChanged.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp;
-
-import de.thedevstack.conversationsplus.entities.Account;
-
-public interface OnStatusChanged {
- public void onStatusChanged(Account account);
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnUpdateBlocklist.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/OnUpdateBlocklist.java
deleted file mode 100644
index ea7b8c62..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/OnUpdateBlocklist.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp;
-
-public interface OnUpdateBlocklist {
- // Use an enum instead of a boolean to make sure we don't run into the boolean trap
- // (`onUpdateBlocklist(true)' doesn't read well, and could be confusing).
- public static enum Status {
- BLOCKED,
- UNBLOCKED
- }
-
- @SuppressWarnings("MethodNameSameAsClassName")
- public void OnUpdateBlocklist(final Status status);
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/PacketReceived.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/PacketReceived.java
deleted file mode 100644
index 6274aaa2..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/PacketReceived.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp;
-
-public abstract interface PacketReceived {
-
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java
deleted file mode 100644
index d5ab9f90..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java
+++ /dev/null
@@ -1,1164 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp;
-
-import android.content.Context;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.SystemClock;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import org.apache.http.conn.ssl.StrictHostnameVerifier;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.math.BigInteger;
-import java.net.ConnectException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeSet;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.X509TrustManager;
-
-import de.thedevstack.android.logcat.Logging;
-import de.thedevstack.conversationsplus.Config;
-import de.thedevstack.conversationsplus.crypto.sasl.DigestMd5;
-import de.thedevstack.conversationsplus.crypto.sasl.Plain;
-import de.thedevstack.conversationsplus.crypto.sasl.SaslMechanism;
-import de.thedevstack.conversationsplus.crypto.sasl.ScramSha1;
-import de.thedevstack.conversationsplus.dto.SrvRecord;
-import de.thedevstack.conversationsplus.entities.Account;
-import de.thedevstack.conversationsplus.generator.IqGenerator;
-import de.thedevstack.conversationsplus.services.XmppConnectionService;
-import de.thedevstack.conversationsplus.utils.CryptoHelper;
-import de.thedevstack.conversationsplus.utils.DNSHelper;
-import de.thedevstack.conversationsplus.utils.Xmlns;
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xml.Tag;
-import de.thedevstack.conversationsplus.xml.TagWriter;
-import de.thedevstack.conversationsplus.xml.XmlReader;
-import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException;
-import de.thedevstack.conversationsplus.xmpp.jid.Jid;
-import de.thedevstack.conversationsplus.xmpp.jingle.OnJinglePacketReceived;
-import de.thedevstack.conversationsplus.xmpp.jingle.stanzas.JinglePacket;
-import de.thedevstack.conversationsplus.xmpp.stanzas.AbstractStanza;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
-import de.thedevstack.conversationsplus.xmpp.stanzas.MessagePacket;
-import de.thedevstack.conversationsplus.xmpp.stanzas.PresencePacket;
-import de.thedevstack.conversationsplus.xmpp.stanzas.csi.ActivePacket;
-import de.thedevstack.conversationsplus.xmpp.stanzas.csi.InactivePacket;
-import de.thedevstack.conversationsplus.xmpp.stanzas.streammgmt.AckPacket;
-import de.thedevstack.conversationsplus.xmpp.stanzas.streammgmt.EnablePacket;
-import de.thedevstack.conversationsplus.xmpp.stanzas.streammgmt.RequestPacket;
-import de.thedevstack.conversationsplus.xmpp.stanzas.streammgmt.ResumePacket;
-
-public class XmppConnection implements Runnable {
- private static final int DEFAULT_PORT = 5222;
- private static final int PACKET_IQ = 0;
- private static final int PACKET_MESSAGE = 1;
- private static final int PACKET_PRESENCE = 2;
- protected Account account;
- private final WakeLock wakeLock;
- private Socket socket;
- private XmlReader tagReader;
- private TagWriter tagWriter;
- private final Features features = new Features(this);
- private boolean shouldBind = true;
- private boolean shouldAuthenticate = true;
- private Element streamFeatures;
- private final HashMap<Jid, Info> disco = new HashMap<>();
-
- private String streamId = null;
- private int smVersion = 3;
- private final SparseArray<String> messageReceipts = new SparseArray<>();
-
- private int stanzasReceived = 0;
- private int stanzasSent = 0;
- private long lastPacketReceived = 0;
- private long lastPingSent = 0;
- private long lastConnect = 0;
- private long lastSessionStarted = 0;
- private int attempt = 0;
- private final Map<String, Pair<IqPacket, OnIqPacketReceived>> packetCallbacks = new Hashtable<>();
- private OnPresencePacketReceived presenceListener = null;
- private OnJinglePacketReceived jingleListener = null;
- private OnIqPacketReceived unregisteredIqListener = null;
- private OnMessagePacketReceived messageListener = null;
- private OnStatusChanged statusListener = null;
- private OnBindListener bindListener = null;
- private final ArrayList<OnAdvancedStreamFeaturesLoaded> advancedStreamFeaturesLoadedListeners = new ArrayList<>();
- private OnMessageAcknowledged acknowledgedListener = null;
- private XmppConnectionService mXmppConnectionService = null;
-
- private SaslMechanism saslMechanism;
-
- public XmppConnection(final Account account, final XmppConnectionService service) {
- this.account = account;
- this.wakeLock = service.getPowerManager().newWakeLock(
- PowerManager.PARTIAL_WAKE_LOCK, account.getJid().toBareJid().toString());
- tagWriter = new TagWriter();
- mXmppConnectionService = service;
- }
-
- protected void changeStatus(final Account.State nextStatus) {
- if (account.getStatus() != nextStatus) {
- if ((nextStatus == Account.State.OFFLINE)
- && (account.getStatus() != Account.State.CONNECTING)
- && (account.getStatus() != Account.State.ONLINE)
- && (account.getStatus() != Account.State.DISABLED)) {
- return;
- }
- if (nextStatus == Account.State.ONLINE) {
- this.attempt = 0;
- }
- account.setStatus(nextStatus);
- if (statusListener != null) {
- statusListener.onStatusChanged(account);
- }
- }
- }
-
- protected void connect() {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": connecting");
- features.encryptionEnabled = false;
- lastConnect = SystemClock.elapsedRealtime();
- lastPingSent = SystemClock.elapsedRealtime();
- this.attempt++;
- try {
- shouldAuthenticate = shouldBind = !account.isOptionSet(Account.OPTION_REGISTER);
- tagReader = new XmlReader(wakeLock);
- tagWriter = new TagWriter();
- packetCallbacks.clear();
- this.changeStatus(Account.State.CONNECTING);
- if (DNSHelper.isIp(account.getServer().toString())) {
- socket = new Socket();
- try {
- socket.connect(new InetSocketAddress(account.getServer().toString(), DEFAULT_PORT), Config.SOCKET_TIMEOUT * 1000);
- } catch (IOException e) {
- throw new UnknownHostException();
- }
- } else {
- socket = new Socket();
- TreeSet<SrvRecord> result = DNSHelper.querySrvRecord(account.getServer());
- if (!result.isEmpty()) {
- for (SrvRecord record : result) {
- try {
- socket.connect(new InetSocketAddress(record.getName(), record.getPort()), Config.SOCKET_TIMEOUT * 1000);
- break;
- } catch (IOException e) {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
- }
- }
- }
- if (result.isEmpty() || !socket.isConnected()){
- try {
- socket.connect(new InetSocketAddress(account.getServer().getDomainpart(), DEFAULT_PORT), Config.SOCKET_TIMEOUT * 1000);
- } catch (IOException e) {
- throw new UnknownHostException();
- }
- }
- }
- final OutputStream out = socket.getOutputStream();
- tagWriter.setOutputStream(out);
- final InputStream in = socket.getInputStream();
- tagReader.setInputStream(in);
- tagWriter.beginDocument();
- sendStartStream();
- Tag nextTag;
- while ((nextTag = tagReader.readTag()) != null) {
- if (nextTag.isStart("stream")) {
- processStream(nextTag);
- break;
- } else {
- throw new IOException("unknown tag on connect");
- }
- }
- if (socket.isConnected()) {
- socket.close();
- }
- } catch (final IncompatibleServerException e) {
- this.changeStatus(Account.State.INCOMPATIBLE_SERVER);
- } catch (final SecurityException e) {
- this.changeStatus(Account.State.SECURITY_ERROR);
- } catch (final UnauthorizedException e) {
- this.changeStatus(Account.State.UNAUTHORIZED);
- } catch (final UnknownHostException | ConnectException e) {
- this.changeStatus(Account.State.SERVER_NOT_FOUND);
- } catch (final IOException | XmlPullParserException | NoSuchAlgorithmException e) {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
- this.changeStatus(Account.State.OFFLINE);
- this.attempt--; //don't count attempt when reconnecting instantly anyway
- } finally {
- if (socket != null) {
- try {
- socket.close();
- } catch (IOException e) {
-
- }
- }
- if (wakeLock.isHeld()) {
- try {
- wakeLock.release();
- } catch (final RuntimeException ignored) {
- }
- }
- }
- }
-
- @Override
- public void run() {
- try {
- if (socket != null) {
- socket.close();
- }
- } catch (final IOException ignored) {
-
- }
- connect();
- }
-
- private void processStream(final Tag currentTag) throws XmlPullParserException,
- IOException, NoSuchAlgorithmException {
- Tag nextTag = tagReader.readTag();
-
- while ((nextTag != null) && (!nextTag.isEnd("stream"))) {
- if (nextTag.isStart("error")) {
- processStreamError(nextTag);
- } else if (nextTag.isStart("features")) {
- processStreamFeatures(nextTag);
- } else if (nextTag.isStart("proceed")) {
- switchOverToTls(nextTag);
- } else if (nextTag.isStart("success")) {
- final String challenge = tagReader.readElement(nextTag).getContent();
- try {
- saslMechanism.getResponse(challenge);
- } catch (final SaslMechanism.AuthenticationException e) {
- disconnect(true);
- Logging.e(Config.LOGTAG, String.valueOf(e));
- }
- Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": logged in");
- account.setKey(Account.PINNED_MECHANISM_KEY,
- String.valueOf(saslMechanism.getPriority()));
- tagReader.reset();
- sendStartStream();
- processStream(tagReader.readTag());
- break;
- } else if (nextTag.isStart("failure")) {
- throw new UnauthorizedException();
- } else if (nextTag.isStart("challenge")) {
- final String challenge = tagReader.readElement(nextTag).getContent();
- final Element response = new Element("response");
- response.setAttribute("xmlns",
- "urn:ietf:params:xml:ns:xmpp-sasl");
- try {
- response.setContent(saslMechanism.getResponse(challenge));
- } catch (final SaslMechanism.AuthenticationException e) {
- // TODO: Send auth abort tag.
- Logging.e(Config.LOGTAG, e.toString());
- }
- tagWriter.writeElement(response);
- } else if (nextTag.isStart("enabled")) {
- final Element enabled = tagReader.readElement(nextTag);
- if ("true".equals(enabled.getAttribute("resume"))) {
- this.streamId = enabled.getAttribute("id");
- Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString()
- + ": stream managment(" + smVersion
- + ") enabled (resumable)");
- } else {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString()
- + ": stream managment(" + smVersion + ") enabled");
- }
- this.lastSessionStarted = SystemClock.elapsedRealtime();
- this.stanzasReceived = 0;
- final RequestPacket r = new RequestPacket(smVersion);
- tagWriter.writeStanzaAsync(r);
- } else if (nextTag.isStart("resumed")) {
- lastPacketReceived = SystemClock.elapsedRealtime();
- final Element resumed = tagReader.readElement(nextTag);
- final String h = resumed.getAttribute("h");
- try {
- final int serverCount = Integer.parseInt(h);
- if (serverCount != stanzasSent) {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString()
- + ": session resumed with lost packages");
- stanzasSent = serverCount;
- } else {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString()
- + ": session resumed");
- }
- if (acknowledgedListener != null) {
- for (int i = 0; i < messageReceipts.size(); ++i) {
- if (serverCount >= messageReceipts.keyAt(i)) {
- acknowledgedListener.onMessageAcknowledged(
- account, messageReceipts.valueAt(i));
- }
- }
- }
- messageReceipts.clear();
- } catch (final NumberFormatException ignored) {
- }
- sendServiceDiscoveryInfo(account.getServer());
- sendServiceDiscoveryInfo(account.getJid().toBareJid());
- sendServiceDiscoveryItems(account.getServer());
- sendInitialPing();
- } else if (nextTag.isStart("r")) {
- tagReader.readElement(nextTag);
- if (Config.EXTENDED_SM_LOGGING) {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": acknowledging stanza #" + this.stanzasReceived);
- }
- final AckPacket ack = new AckPacket(this.stanzasReceived, smVersion);
- tagWriter.writeStanzaAsync(ack);
- } else if (nextTag.isStart("a")) {
- final Element ack = tagReader.readElement(nextTag);
- lastPacketReceived = SystemClock.elapsedRealtime();
- try {
- final int serverSequence = Integer.parseInt(ack.getAttribute("h"));
- if (Config.EXTENDED_SM_LOGGING) {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": server acknowledged stanza #" + serverSequence);
- }
- final String msgId = this.messageReceipts.get(serverSequence);
- if (msgId != null) {
- if (this.acknowledgedListener != null) {
- this.acknowledgedListener.onMessageAcknowledged(
- account, msgId);
- }
- this.messageReceipts.remove(serverSequence);
- }
- } catch (NumberFormatException e) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": server send ack without sequence number");
- }
- } else if (nextTag.isStart("failed")) {
- tagReader.readElement(nextTag);
- Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": resumption failed");
- streamId = null;
- if (account.getStatus() != Account.State.ONLINE) {
- sendBindRequest();
- }
- } else if (nextTag.isStart("iq")) {
- processIq(nextTag);
- } else if (nextTag.isStart("message")) {
- processMessage(nextTag);
- } else if (nextTag.isStart("presence")) {
- processPresence(nextTag);
- }
- nextTag = tagReader.readTag();
- }
- if (account.getStatus() == Account.State.ONLINE) {
- account. setStatus(Account.State.OFFLINE);
- if (statusListener != null) {
- statusListener.onStatusChanged(account);
- }
- }
- }
-
- private void sendInitialPing() {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": sending intial ping");
- final IqPacket iq = new IqPacket(IqPacket.TYPE.GET);
- iq.setFrom(account.getJid());
- iq.addChild("ping", "urn:xmpp:ping");
- this.sendIqPacket(iq, new OnIqPacketReceived() {
- @Override
- public void onIqPacketReceived(final Account account, final IqPacket packet) {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString()
- + ": online with resource " + account.getResource());
- changeStatus(Account.State.ONLINE);
- }
- });
- }
-
- private Element processPacket(final Tag currentTag, final int packetType)
- throws XmlPullParserException, IOException {
- Element element;
- switch (packetType) {
- case PACKET_IQ:
- element = new IqPacket();
- break;
- case PACKET_MESSAGE:
- element = new MessagePacket();
- break;
- case PACKET_PRESENCE:
- element = new PresencePacket();
- break;
- default:
- return null;
- }
- element.setAttributes(currentTag.getAttributes());
- Tag nextTag = tagReader.readTag();
- if (nextTag == null) {
- throw new IOException("interrupted mid tag");
- }
- while (!nextTag.isEnd(element.getName())) {
- if (!nextTag.isNo()) {
- final Element child = tagReader.readElement(nextTag);
- final String type = currentTag.getAttribute("type");
- if (packetType == PACKET_IQ
- && "jingle".equals(child.getName())
- && ("set".equalsIgnoreCase(type) || "get"
- .equalsIgnoreCase(type))) {
- element = new JinglePacket();
- element.setAttributes(currentTag.getAttributes());
- }
- element.addChild(child);
- }
- nextTag = tagReader.readTag();
- if (nextTag == null) {
- throw new IOException("interrupted mid tag");
- }
- }
- if (stanzasReceived == Integer.MAX_VALUE) {
- resetStreamId();
- throw new IOException("time to restart the session. cant handle >2 billion pcks");
- }
- ++stanzasReceived;
- lastPacketReceived = SystemClock.elapsedRealtime();
- return element;
- }
-
- private void processIq(final Tag currentTag) throws XmlPullParserException, IOException {
- final IqPacket packet = (IqPacket) processPacket(currentTag, PACKET_IQ);
-
- if (packet.getId() == null) {
- return; // an iq packet without id is definitely invalid
- }
-
- if (packet instanceof JinglePacket) {
- if (this.jingleListener != null) {
- this.jingleListener.onJinglePacketReceived(account,(JinglePacket) packet);
- }
- } else {
- if (packetCallbacks.containsKey(packet.getId())) {
- final Pair<IqPacket, OnIqPacketReceived> packetCallbackDuple = packetCallbacks.get(packet.getId());
- // Packets to the server should have responses from the server
- if (packetCallbackDuple.first.toServer(account)) {
- if (packet.fromServer(account)) {
- packetCallbackDuple.second.onIqPacketReceived(account, packet);
- packetCallbacks.remove(packet.getId());
- } else {
- Logging.e(Config.LOGTAG,account.getJid().toBareJid().toString()+": ignoring spoofed iq packet");
- }
- } else {
- if (packet.getFrom().equals(packetCallbackDuple.first.getTo())) {
- packetCallbackDuple.second.onIqPacketReceived(account, packet);
- packetCallbacks.remove(packet.getId());
- } else {
- Logging.e(Config.LOGTAG,account.getJid().toBareJid().toString()+": ignoring spoofed iq packet");
- }
- }
- } else if (packet.getType() == IqPacket.TYPE.GET|| packet.getType() == IqPacket.TYPE.SET) {
- this.unregisteredIqListener.onIqPacketReceived(account, packet);
- }
- }
- }
-
- private void processMessage(final Tag currentTag) throws XmlPullParserException, IOException {
- final MessagePacket packet = (MessagePacket) processPacket(currentTag,PACKET_MESSAGE);
- this.messageListener.onMessagePacketReceived(account, packet);
- }
-
- private void processPresence(final Tag currentTag) throws XmlPullParserException, IOException {
- PresencePacket packet = (PresencePacket) processPacket(currentTag, PACKET_PRESENCE);
- this.presenceListener.onPresencePacketReceived(account, packet);
- }
-
- private void sendStartTLS() throws IOException {
- final Tag startTLS = Tag.empty("starttls");
- startTLS.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls");
- tagWriter.writeTag(startTLS);
- }
-
- private void switchOverToTls(final Tag currentTag) throws XmlPullParserException, IOException {
- tagReader.readTag();
- try {
- final SSLContext sc = SSLContext.getInstance("TLS");
- sc.init(null,new X509TrustManager[]{this.mXmppConnectionService.getMemorizingTrustManager()},mXmppConnectionService.getRNG());
- final SSLSocketFactory factory = sc.getSocketFactory();
- final HostnameVerifier verifier = this.mXmppConnectionService.getMemorizingTrustManager().wrapHostnameVerifier(new StrictHostnameVerifier());
- final InetAddress address = socket == null ? null : socket.getInetAddress();
-
- if (factory == null || address == null || verifier == null) {
- throw new IOException("could not setup ssl");
- }
-
- final SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket,address.getHostAddress(), socket.getPort(),true);
-
- if (sslSocket == null) {
- throw new IOException("could not initialize ssl socket");
- }
-
- final String[] supportProtocols;
- final Collection<String> supportedProtocols = new LinkedList<>(
- Arrays.asList(sslSocket.getSupportedProtocols()));
- supportedProtocols.remove("SSLv3");
- supportProtocols = supportedProtocols.toArray(new String[supportedProtocols.size()]);
-
- sslSocket.setEnabledProtocols(supportProtocols);
-
- final String[] cipherSuites = CryptoHelper.getOrderedCipherSuites(
- sslSocket.getSupportedCipherSuites());
- //Logging.d(Config.LOGTAG, "Using ciphers: " + Arrays.toString(cipherSuites));
- if (cipherSuites.length > 0) {
- sslSocket.setEnabledCipherSuites(cipherSuites);
- }
-
- if (!verifier.verify(account.getServer().getDomainpart(),sslSocket.getSession())) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": TLS certificate verification failed");
- throw new SecurityException();
- }
- tagReader.setInputStream(sslSocket.getInputStream());
- tagWriter.setOutputStream(sslSocket.getOutputStream());
- sendStartStream();
- Logging.d(Config.LOGTAG, account.getJid().toBareJid()+ ": TLS connection established");
- features.encryptionEnabled = true;
- processStream(tagReader.readTag());
- sslSocket.close();
- } catch (final NoSuchAlgorithmException | KeyManagementException e1) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": TLS certificate verification failed");
- throw new SecurityException();
- }
- }
-
- private void processStreamFeatures(final Tag currentTag)
- throws XmlPullParserException, IOException {
- this.streamFeatures = tagReader.readElement(currentTag);
- if (this.streamFeatures.hasChild("starttls") && !features.encryptionEnabled) {
- sendStartTLS();
- } else if (this.streamFeatures.hasChild("register")
- && account.isOptionSet(Account.OPTION_REGISTER)
- && features.encryptionEnabled) {
- sendRegistryRequest();
- } else if (!this.streamFeatures.hasChild("register")
- && account.isOptionSet(Account.OPTION_REGISTER)) {
- changeStatus(Account.State.REGISTRATION_NOT_SUPPORTED);
- disconnect(true);
- } else if (this.streamFeatures.hasChild("mechanisms")
- && shouldAuthenticate && features.encryptionEnabled) {
- final List<String> mechanisms = extractMechanisms(streamFeatures
- .findChild("mechanisms"));
- final Element auth = new Element("auth");
- auth.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl");
- if (mechanisms.contains("SCRAM-SHA-1")) {
- saslMechanism = new ScramSha1(tagWriter, account, mXmppConnectionService.getRNG());
- } else if (mechanisms.contains("PLAIN")) {
- saslMechanism = new Plain(tagWriter, account);
- } else if (mechanisms.contains("DIGEST-MD5")) {
- saslMechanism = new DigestMd5(tagWriter, account, mXmppConnectionService.getRNG());
- }
- if (saslMechanism != null) {
- final JSONObject keys = account.getKeys();
- try {
- if (keys.has(Account.PINNED_MECHANISM_KEY) &&
- keys.getInt(Account.PINNED_MECHANISM_KEY) > saslMechanism.getPriority()) {
- Logging.e(Config.LOGTAG, "Auth failed. Authentication mechanism " + saslMechanism.getMechanism() +
- " has lower priority (" + String.valueOf(saslMechanism.getPriority()) +
- ") than pinned priority (" + keys.getInt(Account.PINNED_MECHANISM_KEY) +
- "). Possible downgrade attack?");
- throw new SecurityException();
- }
- } catch (final JSONException e) {
- Logging.d(Config.LOGTAG, "Parse error while checking pinned auth mechanism");
- }
- Logging.d(Config.LOGTAG, account.getJid().toString() + ": Authenticating with " + saslMechanism.getMechanism());
- auth.setAttribute("mechanism", saslMechanism.getMechanism());
- if (!saslMechanism.getClientFirstMessage().isEmpty()) {
- auth.setContent(saslMechanism.getClientFirstMessage());
- }
- tagWriter.writeElement(auth);
- } else {
- throw new IncompatibleServerException();
- }
- } else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:"
- + smVersion)
- && streamId != null) {
- if (Config.EXTENDED_SM_LOGGING) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": resuming after stanza #"+stanzasReceived);
- }
- final ResumePacket resume = new ResumePacket(this.streamId, stanzasReceived, smVersion);
- this.tagWriter.writeStanzaAsync(resume);
- } else if (this.streamFeatures.hasChild("bind") && shouldBind) {
- sendBindRequest();
- } else {
- disconnect(true);
- changeStatus(Account.State.INCOMPATIBLE_SERVER);
- }
- }
-
- private List<String> extractMechanisms(final Element stream) {
- final ArrayList<String> mechanisms = new ArrayList<>(stream
- .getChildren().size());
- for (final Element child : stream.getChildren()) {
- mechanisms.add(child.getContent());
- }
- return mechanisms;
- }
-
- private void sendRegistryRequest() {
- final IqPacket register = new IqPacket(IqPacket.TYPE.GET);
- register.query("jabber:iq:register");
- register.setTo(account.getServer());
- sendIqPacket(register, new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(final Account account, final IqPacket packet) {
- final Element instructions = packet.query().findChild("instructions");
- if (packet.query().hasChild("username")
- && (packet.query().hasChild("password"))) {
- final IqPacket register = new IqPacket(IqPacket.TYPE.SET);
- final Element username = new Element("username").setContent(account.getUsername());
- final Element password = new Element("password").setContent(account.getPassword());
- register.query("jabber:iq:register").addChild(username);
- register.query().addChild(password);
- sendIqPacket(register, new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(final Account account, final IqPacket packet) {
- if (packet.getType() == IqPacket.TYPE.RESULT) {
- account.setOption(Account.OPTION_REGISTER,
- false);
- changeStatus(Account.State.REGISTRATION_SUCCESSFUL);
- } else if (packet.hasChild("error")
- && (packet.findChild("error")
- .hasChild("conflict"))) {
- changeStatus(Account.State.REGISTRATION_CONFLICT);
- } else {
- changeStatus(Account.State.REGISTRATION_FAILED);
- Logging.d(Config.LOGTAG, packet.toString());
- }
- disconnect(true);
- }
- });
- } else {
- changeStatus(Account.State.REGISTRATION_FAILED);
- disconnect(true);
- Logging.d(Config.LOGTAG, account.getJid().toBareJid()
- + ": could not register. instructions are"
- + (instructions != null ? instructions.getContent() : ""));
- }
- }
- });
- }
-
- private void sendBindRequest() {
- while(!mXmppConnectionService.areMessagesInitialized()) {
- try {
- Thread.sleep(500);
- } catch (final InterruptedException ignored) {
- }
- }
- final IqPacket iq = new IqPacket(IqPacket.TYPE.SET);
- iq.addChild("bind", "urn:ietf:params:xml:ns:xmpp-bind")
- .addChild("resource").setContent(account.getResource());
- this.sendUnmodifiedIqPacket(iq, new OnIqPacketReceived() {
- @Override
- public void onIqPacketReceived(final Account account, final IqPacket packet) {
- final Element bind = packet.findChild("bind");
- if (bind != null) {
- final Element jid = bind.findChild("jid");
- if (jid != null && jid.getContent() != null) {
- try {
- account.setResource(Jid.fromString(jid.getContent()).getResourcepart());
- } catch (final InvalidJidException e) {
- // TODO: Handle the case where an external JID is technically invalid?
- }
- if (streamFeatures.hasChild("session")) {
- sendStartSession();
- } else {
- sendPostBindInitialization();
- }
- } else {
- disconnect(true);
- }
- } else {
- disconnect(true);
- }
- }
- });
- }
-
- private void sendStartSession() {
- final IqPacket startSession = new IqPacket(IqPacket.TYPE.SET);
- startSession.addChild("session","urn:ietf:params:xml:ns:xmpp-session");
- this.sendUnmodifiedIqPacket(startSession, new OnIqPacketReceived() {
- @Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- if (packet.getType() == IqPacket.TYPE.RESULT) {
- sendPostBindInitialization();
- } else {
- disconnect(true);
- }
- }
- });
- }
-
- private void sendPostBindInitialization() {
- smVersion = 0;
- if (streamFeatures.hasChild("sm", "urn:xmpp:sm:3")) {
- smVersion = 3;
- } else if (streamFeatures.hasChild("sm", "urn:xmpp:sm:2")) {
- smVersion = 2;
- }
- if (smVersion != 0) {
- final EnablePacket enable = new EnablePacket(smVersion);
- tagWriter.writeStanzaAsync(enable);
- stanzasSent = 0;
- messageReceipts.clear();
- }
- features.carbonsEnabled = false;
- features.blockListRequested = false;
- disco.clear();
- sendServiceDiscoveryInfo(account.getServer());
- sendServiceDiscoveryInfo(account.getJid().toBareJid());
- sendServiceDiscoveryItems(account.getServer());
- if (bindListener != null) {
- bindListener.onBind(account);
- }
- sendInitialPing();
- }
-
- private void sendServiceDiscoveryInfo(final Jid jid) {
- if (disco.containsKey(jid)) {
- if (account.getServer().equals(jid)) {
- enableAdvancedStreamFeatures();
- }
- } else {
- final IqPacket iq = new IqPacket(IqPacket.TYPE.GET);
- iq.setTo(jid);
- iq.query("http://jabber.org/protocol/disco#info");
- this.sendIqPacket(iq, new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(final Account account, final IqPacket packet) {
- final List<Element> elements = packet.query().getChildren();
- final Info info = new Info();
- for (final Element element : elements) {
- if (element.getName().equals("identity")) {
- String type = element.getAttribute("type");
- String category = element.getAttribute("category");
- if (type != null && category != null) {
- info.identities.add(new Pair<>(category,type));
- }
- } else if (element.getName().equals("feature")) {
- info.features.add(element.getAttribute("var"));
- }
- }
- disco.put(jid, info);
-
- if (account.getServer().equals(jid)) {
- enableAdvancedStreamFeatures();
- for (final OnAdvancedStreamFeaturesLoaded listener : advancedStreamFeaturesLoadedListeners) {
- listener.onAdvancedStreamFeaturesAvailable(account);
- }
- }
- }
- });
- }
- }
-
- private void enableAdvancedStreamFeatures() {
- if (getFeatures().carbons() && !features.carbonsEnabled) {
- sendEnableCarbons();
- }
- if (getFeatures().blocking() && !features.blockListRequested) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": Requesting block list");
- this.sendIqPacket(getIqGenerator().generateGetBlockList(), mXmppConnectionService.getIqParser());
- }
- }
-
- private void sendServiceDiscoveryItems(final Jid server) {
- final IqPacket iq = new IqPacket(IqPacket.TYPE.GET);
- iq.setTo(server.toDomainJid());
- iq.query("http://jabber.org/protocol/disco#items");
- this.sendIqPacket(iq, new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(final Account account, final IqPacket packet) {
- final List<Element> elements = packet.query().getChildren();
- for (final Element element : elements) {
- if (element.getName().equals("item")) {
- final Jid jid = element.getAttributeAsJid("jid");
- if (jid != null && !jid.equals(account.getServer())) {
- sendServiceDiscoveryInfo(jid);
- }
- }
- }
- }
- });
- }
-
- private void sendEnableCarbons() {
- final IqPacket iq = new IqPacket(IqPacket.TYPE.SET);
- iq.addChild("enable", "urn:xmpp:carbons:2");
- this.sendIqPacket(iq, new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(final Account account, final IqPacket packet) {
- if (!packet.hasChild("error")) {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid()
- + ": successfully enabled carbons");
- features.carbonsEnabled = true;
- } else {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid()
- + ": error enableing carbons " + packet.toString());
- }
- }
- });
- }
-
- private void processStreamError(final Tag currentTag)
- throws XmlPullParserException, IOException {
- final Element streamError = tagReader.readElement(currentTag);
- if (streamError != null && streamError.hasChild("conflict")) {
- final String resource = account.getResource().split("\\.")[0];
- account.setResource(resource + "." + nextRandomId());
- Logging.d(Config.LOGTAG,
- account.getJid().toBareJid() + ": switching resource due to conflict ("
- + account.getResource() + ")");
- }
- }
-
- private void sendStartStream() throws IOException {
- final Tag stream = Tag.start("stream:stream");
- stream.setAttribute("from", account.getJid().toBareJid().toString());
- stream.setAttribute("to", account.getServer().toString());
- stream.setAttribute("version", "1.0");
- stream.setAttribute("xml:lang", "en");
- stream.setAttribute("xmlns", "jabber:client");
- stream.setAttribute("xmlns:stream", "http://etherx.jabber.org/streams");
- tagWriter.writeTag(stream);
- }
-
- private String nextRandomId() {
- return new BigInteger(50, mXmppConnectionService.getRNG()).toString(32);
- }
-
- public void sendIqPacket(final IqPacket packet, final OnIqPacketReceived callback) {
- packet.setFrom(account.getJid());
- this.sendUnmodifiedIqPacket(packet,callback);
-
- }
-
- private synchronized void sendUnmodifiedIqPacket(final IqPacket packet, final OnIqPacketReceived callback) {
- if (packet.getId() == null) {
- final String id = nextRandomId();
- packet.setAttribute("id", id);
- }
- if (callback != null) {
- if (packet.getId() == null) {
- packet.setId(nextRandomId());
- }
- packetCallbacks.put(packet.getId(), new Pair<>(packet, callback));
- }
- this.sendPacket(packet);
- }
-
- public void sendMessagePacket(final MessagePacket packet) {
- this.sendPacket(packet);
- }
-
- public void sendPresencePacket(final PresencePacket packet) {
- this.sendPacket(packet);
- }
-
- private synchronized void sendPacket(final AbstractStanza packet) {
- if (stanzasSent == Integer.MAX_VALUE) {
- resetStreamId();
- disconnect(true);
- return;
- }
- final String name = packet.getName();
- if (name.equals("iq") || name.equals("message") || name.equals("presence")) {
- ++stanzasSent;
- }
- tagWriter.writeStanzaAsync(packet);
- if (packet instanceof MessagePacket && packet.getId() != null && getFeatures().sm()) {
- if (Config.EXTENDED_SM_LOGGING) {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": requesting ack for message stanza #" + stanzasSent);
- }
- this.messageReceipts.put(stanzasSent, packet.getId());
- tagWriter.writeStanzaAsync(new RequestPacket(this.smVersion));
- }
- }
-
- public void sendPing() {
- if (streamFeatures.hasChild("sm")) {
- tagWriter.writeStanzaAsync(new RequestPacket(smVersion));
- } else {
- final IqPacket iq = new IqPacket(IqPacket.TYPE.GET);
- iq.setFrom(account.getJid());
- iq.addChild("ping", "urn:xmpp:ping");
- this.sendIqPacket(iq, null);
- }
- this.lastPingSent = SystemClock.elapsedRealtime();
- }
-
- public void setOnMessagePacketReceivedListener(
- final OnMessagePacketReceived listener) {
- this.messageListener = listener;
- }
-
- public void setOnUnregisteredIqPacketReceivedListener(
- final OnIqPacketReceived listener) {
- this.unregisteredIqListener = listener;
- }
-
- public void setOnPresencePacketReceivedListener(
- final OnPresencePacketReceived listener) {
- this.presenceListener = listener;
- }
-
- public void setOnJinglePacketReceivedListener(
- final OnJinglePacketReceived listener) {
- this.jingleListener = listener;
- }
-
- public void setOnStatusChangedListener(final OnStatusChanged listener) {
- this.statusListener = listener;
- }
-
- public void setOnBindListener(final OnBindListener listener) {
- this.bindListener = listener;
- }
-
- public void setOnMessageAcknowledgeListener(final OnMessageAcknowledged listener) {
- this.acknowledgedListener = listener;
- }
-
- public void addOnAdvancedStreamFeaturesAvailableListener(final OnAdvancedStreamFeaturesLoaded listener) {
- if (!this.advancedStreamFeaturesLoadedListeners.contains(listener)) {
- this.advancedStreamFeaturesLoadedListeners.add(listener);
- }
- }
-
- public void disconnect(final boolean force) {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": disconnecting");
- try {
- if (force) {
- socket.close();
- return;
- }
- new Thread(new Runnable() {
-
- @Override
- public void run() {
- if (tagWriter.isActive()) {
- tagWriter.finish();
- try {
- while (!tagWriter.finished()) {
- Logging.d(Config.LOGTAG, "not yet finished");
- Thread.sleep(100);
- }
- tagWriter.writeTag(Tag.end("stream:stream"));
- socket.close();
- } catch (final IOException e) {
- Logging.d(Config.LOGTAG,
- "io exception during disconnect");
- } catch (final InterruptedException e) {
- Logging.d(Config.LOGTAG, "interrupted");
- }
- }
- }
- }).start();
- } catch (final IOException e) {
- Logging.d(Config.LOGTAG, "io exception during disconnect");
- }
- }
-
- public void resetStreamId() {
- this.streamId = null;
- }
-
- public List<Jid> findDiscoItemsByFeature(final String feature) {
- final List<Jid> items = new ArrayList<>();
- for (final Entry<Jid, Info> cursor : disco.entrySet()) {
- if (cursor.getValue().features.contains(feature)) {
- items.add(cursor.getKey());
- }
- }
- return items;
- }
-
- public Jid findDiscoItemByFeature(final String feature) {
- final List<Jid> items = findDiscoItemsByFeature(feature);
- if (items.size() >= 1) {
- return items.get(0);
- }
- return null;
- }
-
- public void r() {
- this.tagWriter.writeStanzaAsync(new RequestPacket(smVersion));
- }
-
- public String getMucServer() {
- for (final Entry<Jid, Info> cursor : disco.entrySet()) {
- final Info value = cursor.getValue();
- if (value.features.contains("http://jabber.org/protocol/muc")
- && !value.features.contains("jabber:iq:gateway")
- && !value.identities.contains(new Pair<>("conference","irc"))) {
- return cursor.getKey().toString();
- }
- }
- return null;
- }
-
- public int getTimeToNextAttempt() {
- final int interval = (int) (25 * Math.pow(1.5, attempt));
- final int secondsSinceLast = (int) ((SystemClock.elapsedRealtime() - this.lastConnect) / 1000);
- return interval - secondsSinceLast;
- }
-
- public int getAttempt() {
- return this.attempt;
- }
-
- public Features getFeatures() {
- return this.features;
- }
-
- public long getLastSessionEstablished() {
- final long diff;
- if (this.lastSessionStarted == 0) {
- diff = SystemClock.elapsedRealtime() - this.lastConnect;
- } else {
- diff = SystemClock.elapsedRealtime() - this.lastSessionStarted;
- }
- return System.currentTimeMillis() - diff;
- }
-
- public long getLastConnect() {
- return this.lastConnect;
- }
-
- public long getLastPingSent() {
- return this.lastPingSent;
- }
-
- public long getLastPacketReceived() {
- return this.lastPacketReceived;
- }
-
- public void sendActive() {
- this.sendPacket(new ActivePacket());
- }
-
- public void sendInactive() {
- this.sendPacket(new InactivePacket());
- }
-
- public void resetAttemptCount() {
- this.attempt = 0;
- this.lastConnect = 0;
- }
-
- private class Info {
- public final ArrayList<String> features = new ArrayList<>();
- public final ArrayList<Pair<String,String>> identities = new ArrayList<>();
- }
-
- private class UnauthorizedException extends IOException {
-
- }
-
- private class SecurityException extends IOException {
-
- }
-
- private class IncompatibleServerException extends IOException {
-
- }
-
- public class Features {
- XmppConnection connection;
- private boolean carbonsEnabled = false;
- private boolean encryptionEnabled = false;
- private boolean blockListRequested = false;
-
- public Features(final XmppConnection connection) {
- this.connection = connection;
- }
-
- private boolean hasDiscoFeature(final Jid server, final String feature) {
- return connection.disco.containsKey(server) &&
- connection.disco.get(server).features.contains(feature);
- }
-
- public boolean carbons() {
- return hasDiscoFeature(account.getServer(), "urn:xmpp:carbons:2");
- }
-
- public boolean blocking() {
- return hasDiscoFeature(account.getServer(), Xmlns.BLOCKING);
- }
-
- public boolean register() {
- return hasDiscoFeature(account.getServer(), Xmlns.REGISTER);
- }
-
- public boolean sm() {
- return streamId != null
- || (connection.streamFeatures != null && connection.streamFeatures.hasChild("sm"));
- }
-
- public boolean csi() {
- return connection.streamFeatures != null && connection.streamFeatures.hasChild("csi", "urn:xmpp:csi:0");
- }
-
- public boolean pep() {
- final Pair<String,String> needle = new Pair<>("pubsub","pep");
- Info info = disco.get(account.getServer());
- if (info != null && info.identities.contains(needle)) {
- return true;
- } else {
- info = disco.get(account.getJid().toBareJid());
- return info != null && info.identities.contains(needle);
- }
- }
-
- public boolean mam() {
- if (hasDiscoFeature(account.getJid().toBareJid(), "urn:xmpp:mam:0")) {
- return true;
- } else {
- return hasDiscoFeature(account.getServer(), "urn:xmpp:mam:0");
- }
- }
-
- public boolean advancedStreamFeaturesLoaded() {
- return disco.containsKey(account.getServer());
- }
-
- public boolean rosterVersioning() {
- return connection.streamFeatures != null && connection.streamFeatures.hasChild("ver");
- }
-
- public void setBlockListRequested(boolean value) {
- this.blockListRequested = value;
- }
-
- public boolean httpUpload() {
- return findDiscoItemsByFeature(Xmlns.HTTP_UPLOAD).size() > 0;
- }
- }
-
- private IqGenerator getIqGenerator() {
- return mXmppConnectionService.getIqGenerator();
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/avatar/AvatarPacketGenerator.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/avatar/AvatarPacketGenerator.java
index bb7e557e..ed8a898d 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/avatar/AvatarPacketGenerator.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/avatar/AvatarPacketGenerator.java
@@ -1,10 +1,11 @@
package de.thedevstack.conversationsplus.xmpp.avatar;
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xmpp.jid.Jid;
-import de.thedevstack.conversationsplus.xmpp.pep.Avatar;
import de.thedevstack.conversationsplus.xmpp.pubsub.PubSubPacketGenerator;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
+
+import eu.siacs.conversations.xml.Element;
+import eu.siacs.conversations.xmpp.jid.Jid;
+import eu.siacs.conversations.xmpp.pep.Avatar;
+import eu.siacs.conversations.xmpp.stanzas.IqPacket;
/**
* Generates the IQ Packets for handling Avatars
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/avatar/AvatarPacketParser.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/avatar/AvatarPacketParser.java
index 26d5202f..cf993462 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/avatar/AvatarPacketParser.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/avatar/AvatarPacketParser.java
@@ -1,8 +1,9 @@
package de.thedevstack.conversationsplus.xmpp.avatar;
-import de.thedevstack.conversationsplus.xml.Element;
import de.thedevstack.conversationsplus.xmpp.pubsub.PubSubPacketParser;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
+
+import eu.siacs.conversations.xml.Element;
+import eu.siacs.conversations.xmpp.stanzas.IqPacket;
/**
* Parses the IQ Packets for handling Avatars
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/chatstate/ChatState.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/chatstate/ChatState.java
deleted file mode 100644
index 929d485a..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/chatstate/ChatState.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.chatstate;
-
-import de.thedevstack.conversationsplus.xml.Element;
-
-public enum ChatState {
-
- ACTIVE, INACTIVE, GONE, COMPOSING, PAUSED, mIncomingChatState;
-
- public static ChatState parse(Element element) {
- final String NAMESPACE = "http://jabber.org/protocol/chatstates";
- if (element.hasChild("active",NAMESPACE)) {
- return ACTIVE;
- } else if (element.hasChild("inactive",NAMESPACE)) {
- return INACTIVE;
- } else if (element.hasChild("composing",NAMESPACE)) {
- return COMPOSING;
- } else if (element.hasChild("gone",NAMESPACE)) {
- return GONE;
- } else if (element.hasChild("paused",NAMESPACE)) {
- return PAUSED;
- } else {
- return null;
- }
- }
-
- public static Element toElement(ChatState state) {
- final String NAMESPACE = "http://jabber.org/protocol/chatstates";
- final Element element = new Element(state.toString().toLowerCase());
- element.setAttribute("xmlns",NAMESPACE);
- return element;
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/forms/Data.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/forms/Data.java
deleted file mode 100644
index 591d8ada..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/forms/Data.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.forms;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import de.thedevstack.conversationsplus.xml.Element;
-
-public class Data extends Element {
-
- public Data() {
- super("x");
- this.setAttribute("xmlns","jabber:x:data");
- }
-
- public List<Field> getFields() {
- ArrayList<Field> fields = new ArrayList<Field>();
- for(Element child : getChildren()) {
- if (child.getName().equals("field")) {
- fields.add(Field.parse(child));
- }
- }
- return fields;
- }
-
- public Field getFieldByName(String needle) {
- for(Element child : getChildren()) {
- if (child.getName().equals("field") && needle.equals(child.getAttribute("var"))) {
- return Field.parse(child);
- }
- }
- return null;
- }
-
- public void put(String name, String value) {
- Field field = getFieldByName(name);
- if (field == null) {
- field = new Field(name);
- this.addChild(field);
- }
- field.setValue(value);
- }
-
- public void put(String name, Collection<String> values) {
- Field field = getFieldByName(name);
- if (field == null) {
- field = new Field(name);
- this.addChild(field);
- }
- field.setValues(values);
- }
-
- public void submit() {
- this.setAttribute("type","submit");
- removeNonFieldChildren();
- for(Field field : getFields()) {
- field.removeNonValueChildren();
- }
- }
-
- private void removeNonFieldChildren() {
- for(Iterator<Element> iterator = this.children.iterator(); iterator.hasNext();) {
- Element element = iterator.next();
- if (!element.getName().equals("field")) {
- iterator.remove();
- }
- }
- }
-
- public static Data parse(Element element) {
- Data data = new Data();
- data.setAttributes(element.getAttributes());
- data.setChildren(element.getChildren());
- return data;
- }
-
- public void setFormType(String formType) {
- this.put("FORM_TYPE",formType);
- }
-
- public String getFormType() {
- return this.getAttribute("FORM_TYPE");
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/forms/Field.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/forms/Field.java
deleted file mode 100644
index 9eb2d08d..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/forms/Field.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.forms;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-import de.thedevstack.conversationsplus.xml.Element;
-
-public class Field extends Element {
-
- public Field(String name) {
- super("field");
- this.setAttribute("var",name);
- }
-
- private Field() {
- super("field");
- }
-
- public String getName() {
- return this.getAttribute("var");
- }
-
- public void setValue(String value) {
- this.children.clear();
- this.addChild("value").setContent(value);
- }
-
- public void setValues(Collection<String> values) {
- this.children.clear();
- for(String value : values) {
- this.addChild("value").setContent(value);
- }
- }
-
- public void removeNonValueChildren() {
- for(Iterator<Element> iterator = this.children.iterator(); iterator.hasNext();) {
- Element element = iterator.next();
- if (!element.getName().equals("value")) {
- iterator.remove();
- }
- }
- }
-
- public static Field parse(Element element) {
- Field field = new Field();
- field.setAttributes(element.getAttributes());
- field.setChildren(element.getChildren());
- return field;
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jid/InvalidJidException.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jid/InvalidJidException.java
deleted file mode 100644
index 3c8dd717..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jid/InvalidJidException.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jid;
-
-public class InvalidJidException extends Exception {
-
- // This is probably not the "Java way", but the "Java way" means we'd have a ton of extra tiny,
- // annoying classes floating around. I like this.
- public final static String INVALID_LENGTH = "JID must be between 0 and 3071 characters";
- public final static String INVALID_PART_LENGTH = "JID part must be between 0 and 1023 characters";
- public final static String INVALID_CHARACTER = "JID contains an invalid character";
- public final static String STRINGPREP_FAIL = "The STRINGPREP operation has failed for the given JID";
- public final static String IS_NULL = "JID can not be NULL";
-
- /**
- * Constructs a new {@code Exception} that includes the current stack trace.
- */
- public InvalidJidException() {
- }
-
- /**
- * Constructs a new {@code Exception} with the current stack trace and the
- * specified detail message.
- *
- * @param detailMessage the detail message for this exception.
- */
- public InvalidJidException(final String detailMessage) {
- super(detailMessage);
- }
-
- /**
- * Constructs a new {@code Exception} with the current stack trace, the
- * specified detail message and the specified cause.
- *
- * @param detailMessage the detail message for this exception.
- * @param throwable the cause of this exception.
- */
- public InvalidJidException(final String detailMessage, final Throwable throwable) {
- super(detailMessage, throwable);
- }
-
- /**
- * Constructs a new {@code Exception} with the current stack trace and the
- * specified cause.
- *
- * @param throwable the cause of this exception.
- */
- public InvalidJidException(final Throwable throwable) {
- super(throwable);
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jid/Jid.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jid/Jid.java
deleted file mode 100644
index 5aaf1563..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jid/Jid.java
+++ /dev/null
@@ -1,226 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jid;
-
-import android.util.LruCache;
-
-import net.java.otr4j.session.SessionID;
-
-import java.net.IDN;
-
-import de.thedevstack.conversationsplus.Config;
-import gnu.inet.encoding.Stringprep;
-import gnu.inet.encoding.StringprepException;
-
-/**
- * The `Jid' class provides an immutable representation of a JID.
- */
-public final class Jid {
-
- private static LruCache<String,Jid> cache = new LruCache<>(1024);
-
- private final String localpart;
- private final String domainpart;
- private final String resourcepart;
-
- // It's much more efficient to store the ful JID as well as the parts instead of figuring them
- // all out every time (since some characters are displayed but aren't used for comparisons).
- private final String displayjid;
-
- public String getLocalpart() {
- return localpart;
- }
-
- public String getDomainpart() {
- return IDN.toUnicode(domainpart);
- }
-
- public String getResourcepart() {
- return resourcepart;
- }
-
- public static Jid fromSessionID(final SessionID id) throws InvalidJidException{
- if (id.getUserID().isEmpty()) {
- return Jid.fromString(id.getAccountID());
- } else {
- return Jid.fromString(id.getAccountID()+"/"+id.getUserID());
- }
- }
-
- public static Jid fromString(final String jid) throws InvalidJidException {
- return Jid.fromString(jid, false);
- }
-
- public static Jid fromString(final String jid, final boolean safe) throws InvalidJidException {
- return new Jid(jid, safe);
- }
-
- public static Jid fromParts(final String localpart,
- final String domainpart,
- final String resourcepart) throws InvalidJidException {
- String out;
- if (localpart == null || localpart.isEmpty()) {
- out = domainpart;
- } else {
- out = localpart + "@" + domainpart;
- }
- if (resourcepart != null && !resourcepart.isEmpty()) {
- out = out + "/" + resourcepart;
- }
- return new Jid(out, false);
- }
-
- private Jid(final String jid, final boolean safe) throws InvalidJidException {
- if (jid == null) throw new InvalidJidException(InvalidJidException.IS_NULL);
-
- Jid fromCache = Jid.cache.get(jid);
- if (fromCache != null) {
- displayjid = fromCache.displayjid;
- localpart = fromCache.localpart;
- domainpart = fromCache.domainpart;
- resourcepart = fromCache.resourcepart;
- return;
- }
-
- // Hackish Android way to count the number of chars in a string... should work everywhere.
- final int atCount = jid.length() - jid.replace("@", "").length();
- final int slashCount = jid.length() - jid.replace("/", "").length();
-
- // Throw an error if there's anything obvious wrong with the JID...
- if (jid.isEmpty() || jid.length() > 3071) {
- throw new InvalidJidException(InvalidJidException.INVALID_LENGTH);
- }
-
- // Go ahead and check if the localpart or resourcepart is empty.
- if (jid.startsWith("@") || (jid.endsWith("@") && slashCount == 0) || jid.startsWith("/") || (jid.endsWith("/") && slashCount < 2)) {
- throw new InvalidJidException(InvalidJidException.INVALID_CHARACTER);
- }
-
- String finaljid;
-
- final int domainpartStart;
- final int atLoc = jid.indexOf("@");
- final int slashLoc = jid.indexOf("/");
- // If there is no "@" in the JID (eg. "example.net" or "example.net/resource")
- // or there are one or more "@" signs but they're all in the resourcepart (eg. "example.net/@/rp@"):
- if (atCount == 0 || (atCount > 0 && slashLoc != -1 && atLoc > slashLoc)) {
- localpart = "";
- finaljid = "";
- domainpartStart = 0;
- } else {
- final String lp = jid.substring(0, atLoc);
- try {
- localpart = Config.DISABLE_STRING_PREP || safe ? lp : Stringprep.nodeprep(lp);
- } catch (final StringprepException e) {
- throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e);
- }
- if (localpart.isEmpty() || localpart.length() > 1023) {
- throw new InvalidJidException(InvalidJidException.INVALID_PART_LENGTH);
- }
- domainpartStart = atLoc + 1;
- finaljid = lp + "@";
- }
-
- final String dp;
- if (slashCount > 0) {
- final String rp = jid.substring(slashLoc + 1, jid.length());
- try {
- resourcepart = Config.DISABLE_STRING_PREP || safe ? rp : Stringprep.resourceprep(rp);
- } catch (final StringprepException e) {
- throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e);
- }
- if (resourcepart.isEmpty() || resourcepart.length() > 1023) {
- throw new InvalidJidException(InvalidJidException.INVALID_PART_LENGTH);
- }
- try {
- dp = IDN.toUnicode(Stringprep.nameprep(jid.substring(domainpartStart, slashLoc)), IDN.USE_STD3_ASCII_RULES);
- } catch (final StringprepException e) {
- throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e);
- }
- finaljid = finaljid + dp + "/" + rp;
- } else {
- resourcepart = "";
- try{
- dp = IDN.toUnicode(Stringprep.nameprep(jid.substring(domainpartStart, jid.length())), IDN.USE_STD3_ASCII_RULES);
- } catch (final StringprepException e) {
- throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e);
- }
- finaljid = finaljid + dp;
- }
-
- // Remove trailing "." before storing the domain part.
- if (dp.endsWith(".")) {
- try {
- domainpart = IDN.toASCII(dp.substring(0, dp.length() - 1), IDN.USE_STD3_ASCII_RULES);
- } catch (final IllegalArgumentException e) {
- throw new InvalidJidException(e);
- }
- } else {
- try {
- domainpart = IDN.toASCII(dp, IDN.USE_STD3_ASCII_RULES);
- } catch (final IllegalArgumentException e) {
- throw new InvalidJidException(e);
- }
- }
-
- // TODO: Find a proper domain validation library; validate individual parts, separators, etc.
- if (domainpart.isEmpty() || domainpart.length() > 1023) {
- throw new InvalidJidException(InvalidJidException.INVALID_PART_LENGTH);
- }
-
- Jid.cache.put(jid, this);
-
- this.displayjid = finaljid;
- }
-
- public Jid toBareJid() {
- try {
- return resourcepart.isEmpty() ? this : fromParts(localpart, domainpart, "");
- } catch (final InvalidJidException e) {
- // This should never happen.
- return null;
- }
- }
-
- public Jid toDomainJid() {
- try {
- return resourcepart.isEmpty() && localpart.isEmpty() ? this : fromString(getDomainpart());
- } catch (final InvalidJidException e) {
- // This should never happen.
- return null;
- }
- }
-
- @Override
- public String toString() {
- return displayjid;
- }
-
- @Override
- public boolean equals(final Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- final Jid jid = (Jid) o;
-
- return jid.hashCode() == this.hashCode();
- }
-
- @Override
- public int hashCode() {
- int result = localpart.hashCode();
- result = 31 * result + domainpart.hashCode();
- result = 31 * result + resourcepart.hashCode();
- return result;
- }
-
- public boolean hasLocalpart() {
- return !localpart.isEmpty();
- }
-
- public boolean isBareJid() {
- return this.resourcepart.isEmpty();
- }
-
- public boolean isDomainJid() {
- return !this.hasLocalpart();
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleCandidate.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleCandidate.java
deleted file mode 100644
index bf282293..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleCandidate.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xmpp.jid.Jid;
-
-public class JingleCandidate {
-
- public static int TYPE_UNKNOWN;
- public static int TYPE_DIRECT = 0;
- public static int TYPE_PROXY = 1;
-
- private boolean ours;
- private boolean usedByCounterpart = false;
- private String cid;
- private String host;
- private int port;
- private int type;
- private Jid jid;
- private int priority;
-
- public JingleCandidate(String cid, boolean ours) {
- this.ours = ours;
- this.cid = cid;
- }
-
- public String getCid() {
- return cid;
- }
-
- public void setHost(String host) {
- this.host = host;
- }
-
- public String getHost() {
- return this.host;
- }
-
- public void setJid(final Jid jid) {
- this.jid = jid;
- }
-
- public Jid getJid() {
- return this.jid;
- }
-
- public void setPort(int port) {
- this.port = port;
- }
-
- public int getPort() {
- return this.port;
- }
-
- public void setType(int type) {
- this.type = type;
- }
-
- public void setType(String type) {
- switch (type) {
- case "proxy":
- this.type = TYPE_PROXY;
- break;
- case "direct":
- this.type = TYPE_DIRECT;
- break;
- default:
- this.type = TYPE_UNKNOWN;
- break;
- }
- }
-
- public void setPriority(int i) {
- this.priority = i;
- }
-
- public int getPriority() {
- return this.priority;
- }
-
- public boolean equals(JingleCandidate other) {
- return this.getCid().equals(other.getCid());
- }
-
- public boolean equalValues(JingleCandidate other) {
- return other != null && other.getHost().equals(this.getHost()) && (other.getPort() == this.getPort());
- }
-
- public boolean isOurs() {
- return ours;
- }
-
- public int getType() {
- return this.type;
- }
-
- public static List<JingleCandidate> parse(List<Element> canditates) {
- List<JingleCandidate> parsedCandidates = new ArrayList<>();
- for (Element c : canditates) {
- parsedCandidates.add(JingleCandidate.parse(c));
- }
- return parsedCandidates;
- }
-
- public static JingleCandidate parse(Element candidate) {
- JingleCandidate parsedCandidate = new JingleCandidate(
- candidate.getAttribute("cid"), false);
- parsedCandidate.setHost(candidate.getAttribute("host"));
- parsedCandidate.setJid(candidate.getAttributeAsJid("jid"));
- parsedCandidate.setType(candidate.getAttribute("type"));
- parsedCandidate.setPriority(Integer.parseInt(candidate
- .getAttribute("priority")));
- parsedCandidate
- .setPort(Integer.parseInt(candidate.getAttribute("port")));
- return parsedCandidate;
- }
-
- public Element toElement() {
- Element element = new Element("candidate");
- element.setAttribute("cid", this.getCid());
- element.setAttribute("host", this.getHost());
- element.setAttribute("port", Integer.toString(this.getPort()));
- element.setAttribute("jid", this.getJid().toString());
- element.setAttribute("priority", Integer.toString(this.getPriority()));
- if (this.getType() == TYPE_DIRECT) {
- element.setAttribute("type", "direct");
- } else if (this.getType() == TYPE_PROXY) {
- element.setAttribute("type", "proxy");
- }
- return element;
- }
-
- public void flagAsUsedByCounterpart() {
- this.usedByCounterpart = true;
- }
-
- public boolean isUsedByCounterpart() {
- return this.usedByCounterpart;
- }
-
- public String toString() {
- return this.getHost() + ":" + this.getPort() + " (prio="
- + this.getPriority() + ")";
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java
deleted file mode 100644
index 7885cc0f..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java
+++ /dev/null
@@ -1,960 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.SystemClock;
-
-import de.thedevstack.android.logcat.Logging;
-import de.thedevstack.conversationsplus.Config;
-import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
-import de.thedevstack.conversationsplus.entities.Account;
-import de.thedevstack.conversationsplus.entities.Conversation;
-import de.thedevstack.conversationsplus.entities.Transferable;
-import de.thedevstack.conversationsplus.entities.DownloadableFile;
-import de.thedevstack.conversationsplus.entities.TransferablePlaceholder;
-import de.thedevstack.conversationsplus.entities.Message;
-import de.thedevstack.conversationsplus.persistance.FileBackend;
-import de.thedevstack.conversationsplus.services.XmppConnectionService;
-import de.thedevstack.conversationsplus.utils.MessageUtil;
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xmpp.OnIqPacketReceived;
-import de.thedevstack.conversationsplus.xmpp.jid.Jid;
-import de.thedevstack.conversationsplus.xmpp.jingle.stanzas.Content;
-import de.thedevstack.conversationsplus.xmpp.jingle.stanzas.JinglePacket;
-import de.thedevstack.conversationsplus.xmpp.jingle.stanzas.Reason;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
-
-public class JingleConnection implements Transferable {
-
- private JingleConnectionManager mJingleConnectionManager;
- private XmppConnectionService mXmppConnectionService;
-
- protected static final int JINGLE_STATUS_INITIATED = 0;
- protected static final int JINGLE_STATUS_ACCEPTED = 1;
- protected static final int JINGLE_STATUS_FINISHED = 4;
- protected static final int JINGLE_STATUS_TRANSMITTING = 5;
- protected static final int JINGLE_STATUS_FAILED = 99;
-
- private int ibbBlockSize = 8192;
-
- private int mJingleStatus = -1;
- private int mStatus = Transferable.STATUS_UNKNOWN;
- private Message message;
- private String sessionId;
- private Account account;
- private Jid initiator;
- private Jid responder;
- private List<JingleCandidate> candidates = new ArrayList<>();
- private ConcurrentHashMap<String, JingleSocks5Transport> connections = new ConcurrentHashMap<>();
-
- private String transportId;
- private Element fileOffer;
- private DownloadableFile file = null;
-
- private String contentName;
- private String contentCreator;
-
- private int mProgress = 0;
- private long mLastGuiRefresh = 0;
-
- private boolean receivedCandidate = false;
- private boolean sentCandidate = false;
-
- private boolean acceptedAutomatically = false;
-
- private JingleTransport transport = null;
-
- private OnIqPacketReceived responseListener = new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- if (packet.getType() == IqPacket.TYPE.ERROR) {
- fail();
- }
- }
- };
-
- final OnFileTransmissionStatusChanged onFileTransmissionSatusChanged = new OnFileTransmissionStatusChanged() {
-
- @Override
- public void onFileTransmitted(DownloadableFile file) {
- if (responder.equals(account.getJid())) {
- sendSuccess();
- if (acceptedAutomatically) {
- message.markUnread();
- JingleConnection.this.mXmppConnectionService
- .getNotificationService().push(message);
- }
- MessageUtil.updateFileParams(message);
- mXmppConnectionService.databaseBackend.createMessage(message);
- mXmppConnectionService.markMessage(message,
- Message.STATUS_RECEIVED);
- } else {
- if (message.getEncryption() == Message.ENCRYPTION_PGP || message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
- file.delete();
- }
- }
- Logging.d(Config.LOGTAG,"successfully transmitted file:" + file.getAbsolutePath()+" ("+file.getSha1Sum()+")");
- if (message.getEncryption() != Message.ENCRYPTION_PGP) {
- Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
- intent.setData(Uri.fromFile(file));
- mXmppConnectionService.sendBroadcast(intent);
- }
- }
-
- @Override
- public void onFileTransferAborted() {
- JingleConnection.this.sendCancel();
- JingleConnection.this.fail();
- }
- };
-
- private OnProxyActivated onProxyActivated = new OnProxyActivated() {
-
- @Override
- public void success() {
- if (initiator.equals(account.getJid())) {
- Logging.d(Config.LOGTAG, "we were initiating. sending file");
- transport.send(file, onFileTransmissionSatusChanged);
- } else {
- transport.receive(file, onFileTransmissionSatusChanged);
- Logging.d(Config.LOGTAG, "we were responding. receiving file");
- }
- }
-
- @Override
- public void failed() {
- Logging.d(Config.LOGTAG, "proxy activation failed");
- }
- };
-
- public JingleConnection(JingleConnectionManager mJingleConnectionManager) {
- this.mJingleConnectionManager = mJingleConnectionManager;
- this.mXmppConnectionService = mJingleConnectionManager
- .getXmppConnectionService();
- }
-
- public String getSessionId() {
- return this.sessionId;
- }
-
- public Account getAccount() {
- return this.account;
- }
-
- public Jid getCounterPart() {
- return this.message.getCounterpart();
- }
-
- public void deliverPacket(JinglePacket packet) {
- boolean returnResult = true;
- if (packet.isAction("session-terminate")) {
- Reason reason = packet.getReason();
- if (reason != null) {
- if (reason.hasChild("cancel")) {
- this.fail();
- } else if (reason.hasChild("success")) {
- this.receiveSuccess();
- } else {
- this.fail();
- }
- } else {
- this.fail();
- }
- } else if (packet.isAction("session-accept")) {
- returnResult = receiveAccept(packet);
- } else if (packet.isAction("transport-info")) {
- returnResult = receiveTransportInfo(packet);
- } else if (packet.isAction("transport-replace")) {
- if (packet.getJingleContent().hasIbbTransport()) {
- returnResult = this.receiveFallbackToIbb(packet);
- } else {
- returnResult = false;
- Logging.d(Config.LOGTAG, "trying to fallback to something unknown"
- + packet.toString());
- }
- } else if (packet.isAction("transport-accept")) {
- returnResult = this.receiveTransportAccept(packet);
- } else {
- Logging.d(Config.LOGTAG, "packet arrived in connection. action was "
- + packet.getAction());
- returnResult = false;
- }
- IqPacket response;
- if (returnResult) {
- response = packet.generateResponse(IqPacket.TYPE.RESULT);
-
- } else {
- response = packet.generateResponse(IqPacket.TYPE.ERROR);
- }
- mXmppConnectionService.sendIqPacket(account,response,null);
- }
-
- public void init(Message message) {
- this.contentCreator = "initiator";
- this.contentName = this.mJingleConnectionManager.nextRandomId();
- this.message = message;
- this.message.setTransferable(this);
- this.mStatus = Transferable.STATUS_UPLOADING;
- this.account = message.getConversation().getAccount();
- this.initiator = this.account.getJid();
- this.responder = this.message.getCounterpart();
- this.sessionId = this.mJingleConnectionManager.nextRandomId();
- if (this.candidates.size() > 0) {
- this.sendInitRequest();
- } else {
- this.mJingleConnectionManager.getPrimaryCandidate(account,
- new OnPrimaryCandidateFound() {
-
- @Override
- public void onPrimaryCandidateFound(boolean success,
- final JingleCandidate candidate) {
- if (success) {
- final JingleSocks5Transport socksConnection = new JingleSocks5Transport(
- JingleConnection.this, candidate);
- connections.put(candidate.getCid(),
- socksConnection);
- socksConnection
- .connect(new OnTransportConnected() {
-
- @Override
- public void failed() {
- Logging.d(Config.LOGTAG,
- "connection to our own primary candidete failed");
- sendInitRequest();
- }
-
- @Override
- public void established() {
- Logging.d(Config.LOGTAG,
- "succesfully connected to our own primary candidate");
- mergeCandidate(candidate);
- sendInitRequest();
- }
- });
- mergeCandidate(candidate);
- } else {
- Logging.d(Config.LOGTAG,
- "no primary candidate of our own was found");
- sendInitRequest();
- }
- }
- });
- }
-
- }
-
- public void init(Account account, JinglePacket packet) {
- this.mJingleStatus = JINGLE_STATUS_INITIATED;
- Conversation conversation = this.mXmppConnectionService
- .findOrCreateConversation(account,
- packet.getFrom().toBareJid(), false);
- this.message = new Message(conversation, "", Message.ENCRYPTION_NONE);
- this.message.setStatus(Message.STATUS_RECEIVED);
- this.mStatus = Transferable.STATUS_OFFER;
- this.message.setTransferable(this);
- final Jid from = packet.getFrom();
- this.message.setCounterpart(from);
- this.account = account;
- this.initiator = packet.getFrom();
- this.responder = this.account.getJid();
- this.sessionId = packet.getSessionId();
- Content content = packet.getJingleContent();
- this.contentCreator = content.getAttribute("creator");
- this.contentName = content.getAttribute("name");
- this.transportId = content.getTransportId();
- this.mergeCandidates(JingleCandidate.parse(content.socks5transport()
- .getChildren()));
- this.fileOffer = packet.getJingleContent().getFileOffer();
-
- mXmppConnectionService.sendIqPacket(account,packet.generateResponse(IqPacket.TYPE.RESULT),null);
-
- if (fileOffer != null) {
- Element fileSize = fileOffer.findChild("size");
- Element fileNameElement = fileOffer.findChild("name");
- if (fileNameElement != null) {
- String[] filename = fileNameElement.getContent()
- .toLowerCase(Locale.US).toLowerCase().split("\\.");
- String extension = filename[filename.length - 1];
- if (Arrays.asList(VALID_IMAGE_EXTENSIONS).contains(extension)) {
- message.setType(Message.TYPE_IMAGE);
- message.setRelativeFilePath(message.getUuid()+"."+extension);
- } else if (Arrays.asList(VALID_CRYPTO_EXTENSIONS).contains(
- filename[filename.length - 1])) {
- if (filename.length == 3) {
- extension = filename[filename.length - 2];
- if (Arrays.asList(VALID_IMAGE_EXTENSIONS).contains(extension)) {
- message.setType(Message.TYPE_IMAGE);
- message.setRelativeFilePath(message.getUuid()+"."+extension);
- } else {
- message.setType(Message.TYPE_FILE);
- }
- if (filename[filename.length - 1].equals("otr")) {
- message.setEncryption(Message.ENCRYPTION_OTR);
- } else {
- message.setEncryption(Message.ENCRYPTION_PGP);
- }
- }
- } else {
- message.setType(Message.TYPE_FILE);
- }
- if (message.getType() == Message.TYPE_FILE) {
- String suffix = "";
- if (!fileNameElement.getContent().isEmpty()) {
- String parts[] = fileNameElement.getContent().split("/");
- suffix = parts[parts.length - 1];
- if (message.getEncryption() == Message.ENCRYPTION_OTR && suffix.endsWith(".otr")) {
- suffix = suffix.substring(0,suffix.length() - 4);
- } else if (message.getEncryption() == Message.ENCRYPTION_PGP && (suffix.endsWith(".pgp") || suffix.endsWith(".gpg"))) {
- suffix = suffix.substring(0,suffix.length() - 4);
- }
- }
- message.setRelativeFilePath(message.getUuid()+"_"+suffix);
- }
- long size = Long.parseLong(fileSize.getContent());
- message.setBody(Long.toString(size));
- conversation.add(message);
- mXmppConnectionService.updateConversationUi();
- if (size <= ConversationsPlusPreferences.autoAcceptFileSize()
- && mXmppConnectionService.isDownloadAllowedInConnection()) {
- Logging.d(Config.LOGTAG, "auto accepting file from "
- + packet.getFrom());
- this.acceptedAutomatically = true;
- this.sendAccept();
- } else {
- message.markUnread();
- Logging.d(Config.LOGTAG,
- "not auto accepting new file offer with size: "
- + size
- + " allowed size:"
- + ConversationsPlusPreferences.autoAcceptFileSize());
- this.mXmppConnectionService.getNotificationService()
- .push(message);
- }
- this.file = FileBackend.getFile(message, false);
- if (message.getEncryption() == Message.ENCRYPTION_OTR) {
- byte[] key = conversation.getSymmetricKey();
- if (key == null) {
- this.sendCancel();
- this.fail();
- return;
- } else {
- this.file.setKey(key);
- }
- }
- this.file.setExpectedSize(size);
- } else {
- this.sendCancel();
- this.fail();
- }
- } else {
- this.sendCancel();
- this.fail();
- }
- }
-
- private void sendInitRequest() {
- JinglePacket packet = this.bootstrapPacket("session-initiate");
- Content content = new Content(this.contentCreator, this.contentName);
- if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) {
- content.setTransportId(this.transportId);
- this.file = FileBackend.getFile(message, false);
- if (message.getEncryption() == Message.ENCRYPTION_OTR) {
- Conversation conversation = this.message.getConversation();
- if (!this.mXmppConnectionService.renewSymmetricKey(conversation)) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": could not set symmetric key");
- cancel();
- }
- content.setFileOffer(this.file, true);
- this.file.setKey(conversation.getSymmetricKey());
- } else {
- content.setFileOffer(this.file, false);
- }
- this.transportId = this.mJingleConnectionManager.nextRandomId();
- content.setTransportId(this.transportId);
- content.socks5transport().setChildren(getCandidatesAsElements());
- packet.setContent(content);
- this.sendJinglePacket(packet,new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- if (packet.getType() != IqPacket.TYPE.ERROR) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": other party received offer");
- mJingleStatus = JINGLE_STATUS_INITIATED;
- mXmppConnectionService.markMessage(message, Message.STATUS_OFFERED);
- } else {
- fail();
- }
- }
- });
-
- }
- }
-
- private List<Element> getCandidatesAsElements() {
- List<Element> elements = new ArrayList<>();
- for (JingleCandidate c : this.candidates) {
- if (c.isOurs()) {
- elements.add(c.toElement());
- }
- }
- return elements;
- }
-
- private void sendAccept() {
- mJingleStatus = JINGLE_STATUS_ACCEPTED;
- this.mStatus = Transferable.STATUS_DOWNLOADING;
- mXmppConnectionService.updateConversationUi();
- this.mJingleConnectionManager.getPrimaryCandidate(this.account, new OnPrimaryCandidateFound() {
- @Override
- public void onPrimaryCandidateFound(boolean success, final JingleCandidate candidate) {
- final JinglePacket packet = bootstrapPacket("session-accept");
- final Content content = new Content(contentCreator,contentName);
- content.setFileOffer(fileOffer);
- content.setTransportId(transportId);
- if (success && candidate != null && !equalCandidateExists(candidate)) {
- final JingleSocks5Transport socksConnection = new JingleSocks5Transport(
- JingleConnection.this,
- candidate);
- connections.put(candidate.getCid(), socksConnection);
- socksConnection.connect(new OnTransportConnected() {
-
- @Override
- public void failed() {
- Logging.d(Config.LOGTAG,"connection to our own primary candidate failed");
- content.socks5transport().setChildren(getCandidatesAsElements());
- packet.setContent(content);
- sendJinglePacket(packet);
- connectNextCandidate();
- }
-
- @Override
- public void established() {
- Logging.d(Config.LOGTAG, "connected to primary candidate");
- mergeCandidate(candidate);
- content.socks5transport().setChildren(getCandidatesAsElements());
- packet.setContent(content);
- sendJinglePacket(packet);
- connectNextCandidate();
- }
- });
- } else {
- Logging.d(Config.LOGTAG,"did not find a primary candidate for ourself");
- content.socks5transport().setChildren(getCandidatesAsElements());
- packet.setContent(content);
- sendJinglePacket(packet);
- connectNextCandidate();
- }
- }
- });
- }
-
- private JinglePacket bootstrapPacket(String action) {
- JinglePacket packet = new JinglePacket();
- packet.setAction(action);
- packet.setFrom(account.getJid());
- packet.setTo(this.message.getCounterpart());
- packet.setSessionId(this.sessionId);
- packet.setInitiator(this.initiator);
- return packet;
- }
-
- private void sendJinglePacket(JinglePacket packet) {
- mXmppConnectionService.sendIqPacket(account,packet,responseListener);
- }
-
- private void sendJinglePacket(JinglePacket packet, OnIqPacketReceived callback) {
- mXmppConnectionService.sendIqPacket(account,packet,callback);
- }
-
- private boolean receiveAccept(JinglePacket packet) {
- Content content = packet.getJingleContent();
- mergeCandidates(JingleCandidate.parse(content.socks5transport()
- .getChildren()));
- this.mJingleStatus = JINGLE_STATUS_ACCEPTED;
- mXmppConnectionService.markMessage(message, Message.STATUS_UNSEND);
- this.connectNextCandidate();
- return true;
- }
-
- private boolean receiveTransportInfo(JinglePacket packet) {
- Content content = packet.getJingleContent();
- if (content.hasSocks5Transport()) {
- if (content.socks5transport().hasChild("activated")) {
- if ((this.transport != null) && (this.transport instanceof JingleSocks5Transport)) {
- onProxyActivated.success();
- } else {
- String cid = content.socks5transport().findChild("activated").getAttribute("cid");
- Logging.d(Config.LOGTAG, "received proxy activated (" + cid
- + ")prior to choosing our own transport");
- JingleSocks5Transport connection = this.connections.get(cid);
- if (connection != null) {
- connection.setActivated(true);
- } else {
- Logging.d(Config.LOGTAG, "activated connection not found");
- this.sendCancel();
- this.fail();
- }
- }
- return true;
- } else if (content.socks5transport().hasChild("proxy-error")) {
- onProxyActivated.failed();
- return true;
- } else if (content.socks5transport().hasChild("candidate-error")) {
- Logging.d(Config.LOGTAG, "received candidate error");
- this.receivedCandidate = true;
- if ((mJingleStatus == JINGLE_STATUS_ACCEPTED)
- && (this.sentCandidate)) {
- this.connect();
- }
- return true;
- } else if (content.socks5transport().hasChild("candidate-used")) {
- String cid = content.socks5transport()
- .findChild("candidate-used").getAttribute("cid");
- if (cid != null) {
- Logging.d(Config.LOGTAG, "candidate used by counterpart:" + cid);
- JingleCandidate candidate = getCandidate(cid);
- candidate.flagAsUsedByCounterpart();
- this.receivedCandidate = true;
- if ((mJingleStatus == JINGLE_STATUS_ACCEPTED)
- && (this.sentCandidate)) {
- this.connect();
- } else {
- Logging.d(Config.LOGTAG,
- "ignoring because file is already in transmission or we havent sent our candidate yet");
- }
- return true;
- } else {
- return false;
- }
- } else {
- return false;
- }
- } else {
- return true;
- }
- }
-
- private void connect() {
- final JingleSocks5Transport connection = chooseConnection();
- this.transport = connection;
- if (connection == null) {
- Logging.d(Config.LOGTAG, "could not find suitable candidate");
- this.disconnectSocks5Connections();
- if (this.initiator.equals(account.getJid())) {
- this.sendFallbackToIbb();
- }
- } else {
- this.mJingleStatus = JINGLE_STATUS_TRANSMITTING;
- if (connection.needsActivation()) {
- if (connection.getCandidate().isOurs()) {
- Logging.d(Config.LOGTAG, "candidate "
- + connection.getCandidate().getCid()
- + " was our proxy. going to activate");
- IqPacket activation = new IqPacket(IqPacket.TYPE.SET);
- activation.setTo(connection.getCandidate().getJid());
- activation.query("http://jabber.org/protocol/bytestreams")
- .setAttribute("sid", this.getSessionId());
- activation.query().addChild("activate")
- .setContent(this.getCounterPart().toString());
- mXmppConnectionService.sendIqPacket(account,activation,
- new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(Account account,
- IqPacket packet) {
- if (packet.getType() == IqPacket.TYPE.ERROR) {
- onProxyActivated.failed();
- } else {
- onProxyActivated.success();
- sendProxyActivated(connection
- .getCandidate().getCid());
- }
- }
- });
- } else {
- Logging.d(Config.LOGTAG,
- "candidate "
- + connection.getCandidate().getCid()
- + " was a proxy. waiting for other party to activate");
- }
- } else {
- if (initiator.equals(account.getJid())) {
- Logging.d(Config.LOGTAG, "we were initiating. sending file");
- connection.send(file, onFileTransmissionSatusChanged);
- } else {
- Logging.d(Config.LOGTAG, "we were responding. receiving file");
- connection.receive(file, onFileTransmissionSatusChanged);
- }
- }
- }
- }
-
- private JingleSocks5Transport chooseConnection() {
- JingleSocks5Transport connection = null;
- for (Entry<String, JingleSocks5Transport> cursor : connections
- .entrySet()) {
- JingleSocks5Transport currentConnection = cursor.getValue();
- // Logging.d(Config.LOGTAG,"comparing candidate: "+currentConnection.getCandidate().toString());
- if (currentConnection.isEstablished()
- && (currentConnection.getCandidate().isUsedByCounterpart() || (!currentConnection
- .getCandidate().isOurs()))) {
- // Logging.d(Config.LOGTAG,"is usable");
- if (connection == null) {
- connection = currentConnection;
- } else {
- if (connection.getCandidate().getPriority() < currentConnection
- .getCandidate().getPriority()) {
- connection = currentConnection;
- } else if (connection.getCandidate().getPriority() == currentConnection
- .getCandidate().getPriority()) {
- // Logging.d(Config.LOGTAG,"found two candidates with same priority");
- if (initiator.equals(account.getJid())) {
- if (currentConnection.getCandidate().isOurs()) {
- connection = currentConnection;
- }
- } else {
- if (!currentConnection.getCandidate().isOurs()) {
- connection = currentConnection;
- }
- }
- }
- }
- }
- }
- return connection;
- }
-
- private void sendSuccess() {
- JinglePacket packet = bootstrapPacket("session-terminate");
- Reason reason = new Reason();
- reason.addChild("success");
- packet.setReason(reason);
- this.sendJinglePacket(packet);
- this.disconnectSocks5Connections();
- this.mJingleStatus = JINGLE_STATUS_FINISHED;
- this.message.setStatus(Message.STATUS_RECEIVED);
- this.message.setTransferable(null);
- this.mXmppConnectionService.updateMessage(message);
- this.mJingleConnectionManager.finishConnection(this);
- }
-
- private void sendFallbackToIbb() {
- Logging.d(Config.LOGTAG, "sending fallback to ibb");
- JinglePacket packet = this.bootstrapPacket("transport-replace");
- Content content = new Content(this.contentCreator, this.contentName);
- this.transportId = this.mJingleConnectionManager.nextRandomId();
- content.setTransportId(this.transportId);
- content.ibbTransport().setAttribute("block-size",
- Integer.toString(this.ibbBlockSize));
- packet.setContent(content);
- this.sendJinglePacket(packet);
- }
-
- private boolean receiveFallbackToIbb(JinglePacket packet) {
- Logging.d(Config.LOGTAG, "receiving fallack to ibb");
- String receivedBlockSize = packet.getJingleContent().ibbTransport()
- .getAttribute("block-size");
- if (receivedBlockSize != null) {
- int bs = Integer.parseInt(receivedBlockSize);
- if (bs > this.ibbBlockSize) {
- this.ibbBlockSize = bs;
- }
- }
- this.transportId = packet.getJingleContent().getTransportId();
- this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize);
- this.transport.receive(file, onFileTransmissionSatusChanged);
- JinglePacket answer = bootstrapPacket("transport-accept");
- Content content = new Content("initiator", "a-file-offer");
- content.setTransportId(this.transportId);
- content.ibbTransport().setAttribute("block-size",
- Integer.toString(this.ibbBlockSize));
- answer.setContent(content);
- this.sendJinglePacket(answer);
- return true;
- }
-
- private boolean receiveTransportAccept(JinglePacket packet) {
- if (packet.getJingleContent().hasIbbTransport()) {
- String receivedBlockSize = packet.getJingleContent().ibbTransport()
- .getAttribute("block-size");
- if (receivedBlockSize != null) {
- int bs = Integer.parseInt(receivedBlockSize);
- if (bs > this.ibbBlockSize) {
- this.ibbBlockSize = bs;
- }
- }
- this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize);
- this.transport.connect(new OnTransportConnected() {
-
- @Override
- public void failed() {
- Logging.d(Config.LOGTAG, "ibb open failed");
- }
-
- @Override
- public void established() {
- JingleConnection.this.transport.send(file,
- onFileTransmissionSatusChanged);
- }
- });
- return true;
- } else {
- return false;
- }
- }
-
- private void receiveSuccess() {
- this.mJingleStatus = JINGLE_STATUS_FINISHED;
- this.mXmppConnectionService.markMessage(this.message,Message.STATUS_SEND_RECEIVED);
- this.disconnectSocks5Connections();
- if (this.transport != null && this.transport instanceof JingleInbandTransport) {
- this.transport.disconnect();
- }
- this.message.setTransferable(null);
- this.mJingleConnectionManager.finishConnection(this);
- }
-
- public void cancel() {
- this.disconnectSocks5Connections();
- if (this.transport != null && this.transport instanceof JingleInbandTransport) {
- this.transport.disconnect();
- }
- this.sendCancel();
- this.mJingleConnectionManager.finishConnection(this);
- if (this.responder.equals(account.getJid())) {
- this.message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_FAILED));
- if (this.file!=null) {
- file.delete();
- }
- this.mXmppConnectionService.updateConversationUi();
- } else {
- this.mXmppConnectionService.markMessage(this.message,
- Message.STATUS_SEND_FAILED);
- this.message.setTransferable(null);
- }
- }
-
- private void fail() {
- this.mJingleStatus = JINGLE_STATUS_FAILED;
- this.disconnectSocks5Connections();
- if (this.transport != null && this.transport instanceof JingleInbandTransport) {
- this.transport.disconnect();
- }
- if (this.message != null) {
- if (this.responder.equals(account.getJid())) {
- this.message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_FAILED));
- if (this.file!=null) {
- file.delete();
- }
- this.mXmppConnectionService.updateConversationUi();
- } else {
- this.mXmppConnectionService.markMessage(this.message,
- Message.STATUS_SEND_FAILED);
- this.message.setTransferable(null);
- }
- }
- this.mJingleConnectionManager.finishConnection(this);
- }
-
- private void sendCancel() {
- JinglePacket packet = bootstrapPacket("session-terminate");
- Reason reason = new Reason();
- reason.addChild("cancel");
- packet.setReason(reason);
- this.sendJinglePacket(packet);
- }
-
- private void connectNextCandidate() {
- for (JingleCandidate candidate : this.candidates) {
- if ((!connections.containsKey(candidate.getCid()) && (!candidate
- .isOurs()))) {
- this.connectWithCandidate(candidate);
- return;
- }
- }
- this.sendCandidateError();
- }
-
- private void connectWithCandidate(final JingleCandidate candidate) {
- final JingleSocks5Transport socksConnection = new JingleSocks5Transport(
- this, candidate);
- connections.put(candidate.getCid(), socksConnection);
- socksConnection.connect(new OnTransportConnected() {
-
- @Override
- public void failed() {
- Logging.d(Config.LOGTAG,
- "connection failed with " + candidate.getHost() + ":"
- + candidate.getPort());
- connectNextCandidate();
- }
-
- @Override
- public void established() {
- Logging.d(Config.LOGTAG,
- "established connection with " + candidate.getHost()
- + ":" + candidate.getPort());
- sendCandidateUsed(candidate.getCid());
- }
- });
- }
-
- private void disconnectSocks5Connections() {
- Iterator<Entry<String, JingleSocks5Transport>> it = this.connections
- .entrySet().iterator();
- while (it.hasNext()) {
- Entry<String, JingleSocks5Transport> pairs = it.next();
- pairs.getValue().disconnect();
- it.remove();
- }
- }
-
- private void sendProxyActivated(String cid) {
- JinglePacket packet = bootstrapPacket("transport-info");
- Content content = new Content(this.contentCreator, this.contentName);
- content.setTransportId(this.transportId);
- content.socks5transport().addChild("activated")
- .setAttribute("cid", cid);
- packet.setContent(content);
- this.sendJinglePacket(packet);
- }
-
- private void sendCandidateUsed(final String cid) {
- JinglePacket packet = bootstrapPacket("transport-info");
- Content content = new Content(this.contentCreator, this.contentName);
- content.setTransportId(this.transportId);
- content.socks5transport().addChild("candidate-used")
- .setAttribute("cid", cid);
- packet.setContent(content);
- this.sentCandidate = true;
- if ((receivedCandidate) && (mJingleStatus == JINGLE_STATUS_ACCEPTED)) {
- connect();
- }
- this.sendJinglePacket(packet);
- }
-
- private void sendCandidateError() {
- JinglePacket packet = bootstrapPacket("transport-info");
- Content content = new Content(this.contentCreator, this.contentName);
- content.setTransportId(this.transportId);
- content.socks5transport().addChild("candidate-error");
- packet.setContent(content);
- this.sentCandidate = true;
- if ((receivedCandidate) && (mJingleStatus == JINGLE_STATUS_ACCEPTED)) {
- connect();
- }
- this.sendJinglePacket(packet);
- }
-
- public Jid getInitiator() {
- return this.initiator;
- }
-
- public Jid getResponder() {
- return this.responder;
- }
-
- public int getJingleStatus() {
- return this.mJingleStatus;
- }
-
- private boolean equalCandidateExists(JingleCandidate candidate) {
- for (JingleCandidate c : this.candidates) {
- if (c.equalValues(candidate)) {
- return true;
- }
- }
- return false;
- }
-
- private void mergeCandidate(JingleCandidate candidate) {
- for (JingleCandidate c : this.candidates) {
- if (c.equals(candidate)) {
- return;
- }
- }
- this.candidates.add(candidate);
- }
-
- private void mergeCandidates(List<JingleCandidate> candidates) {
- for (JingleCandidate c : candidates) {
- mergeCandidate(c);
- }
- }
-
- private JingleCandidate getCandidate(String cid) {
- for (JingleCandidate c : this.candidates) {
- if (c.getCid().equals(cid)) {
- return c;
- }
- }
- return null;
- }
-
- public void updateProgress(int i) {
- this.mProgress = i;
- if (SystemClock.elapsedRealtime() - this.mLastGuiRefresh > Config.PROGRESS_UI_UPDATE_INTERVAL) {
- this.mLastGuiRefresh = SystemClock.elapsedRealtime();
- mXmppConnectionService.updateConversationUi();
- }
- }
-
- interface OnProxyActivated {
- public void success();
-
- public void failed();
- }
-
- public boolean hasTransportId(String sid) {
- return sid.equals(this.transportId);
- }
-
- public JingleTransport getTransport() {
- return this.transport;
- }
-
- public boolean start() {
- if (account.getStatus() == Account.State.ONLINE) {
- if (mJingleStatus == JINGLE_STATUS_INITIATED) {
- new Thread(new Runnable() {
-
- @Override
- public void run() {
- sendAccept();
- }
- }).start();
- }
- return true;
- } else {
- return false;
- }
- }
-
- @Override
- public int getStatus() {
- return this.mStatus;
- }
-
- @Override
- public long getFileSize() {
- if (this.file != null) {
- return this.file.getExpectedSize();
- } else {
- return 0;
- }
- }
-
- @Override
- public int getProgress() {
- return this.mProgress;
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java
deleted file mode 100644
index 861082d8..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnectionManager.java
+++ /dev/null
@@ -1,171 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import android.annotation.SuppressLint;
-
-import de.thedevstack.android.logcat.Logging;
-import de.thedevstack.conversationsplus.Config;
-import de.thedevstack.conversationsplus.entities.Account;
-import de.thedevstack.conversationsplus.entities.Transferable;
-import de.thedevstack.conversationsplus.entities.Message;
-import de.thedevstack.conversationsplus.services.AbstractConnectionManager;
-import de.thedevstack.conversationsplus.services.XmppConnectionService;
-import de.thedevstack.conversationsplus.utils.Xmlns;
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xmpp.OnIqPacketReceived;
-import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException;
-import de.thedevstack.conversationsplus.xmpp.jid.Jid;
-import de.thedevstack.conversationsplus.xmpp.jingle.stanzas.JinglePacket;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
-
-public class JingleConnectionManager extends AbstractConnectionManager {
- private List<JingleConnection> connections = new CopyOnWriteArrayList<>();
-
- private HashMap<Jid, JingleCandidate> primaryCandidates = new HashMap<>();
-
- @SuppressLint("TrulyRandom")
- private SecureRandom random = new SecureRandom();
-
- public JingleConnectionManager(XmppConnectionService service) {
- super(service);
- }
-
- public void deliverPacket(Account account, JinglePacket packet) {
- if (packet.isAction("session-initiate")) {
- JingleConnection connection = new JingleConnection(this);
- connection.init(account, packet);
- connections.add(connection);
- } else {
- for (JingleConnection connection : connections) {
- if (connection.getAccount() == account
- && connection.getSessionId().equals(
- packet.getSessionId())
- && connection.getCounterPart().equals(packet.getFrom())) {
- connection.deliverPacket(packet);
- return;
- }
- }
- IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR);
- Element error = response.addChild("error");
- error.setAttribute("type", "cancel");
- error.addChild("item-not-found",
- "urn:ietf:params:xml:ns:xmpp-stanzas");
- error.addChild("unknown-session", "urn:xmpp:jingle:errors:1");
- account.getXmppConnection().sendIqPacket(response, null);
- }
- }
-
- public JingleConnection createNewConnection(Message message) {
- Transferable old = message.getTransferable();
- if (old != null) {
- old.cancel();
- }
- JingleConnection connection = new JingleConnection(this);
- mXmppConnectionService.markMessage(message,Message.STATUS_WAITING);
- connection.init(message);
- this.connections.add(connection);
- return connection;
- }
-
- public JingleConnection createNewConnection(final JinglePacket packet) {
- JingleConnection connection = new JingleConnection(this);
- this.connections.add(connection);
- return connection;
- }
-
- public void finishConnection(JingleConnection connection) {
- this.connections.remove(connection);
- }
-
- public void getPrimaryCandidate(Account account,
- final OnPrimaryCandidateFound listener) {
- if (Config.NO_PROXY_LOOKUP) {
- listener.onPrimaryCandidateFound(false, null);
- return;
- }
- if (!this.primaryCandidates.containsKey(account.getJid().toBareJid())) {
- final Jid proxy = account.getXmppConnection().findDiscoItemByFeature(Xmlns.BYTE_STREAMS);
- if (proxy != null) {
- IqPacket iq = new IqPacket(IqPacket.TYPE.GET);
- iq.setTo(proxy);
- iq.query(Xmlns.BYTE_STREAMS);
- account.getXmppConnection().sendIqPacket(iq,new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- Element streamhost = packet.query().findChild("streamhost",Xmlns.BYTE_STREAMS);
- final String host = streamhost == null ? null : streamhost.getAttribute("host");
- final String port = streamhost == null ? null : streamhost.getAttribute("port");
- if (host != null && port != null) {
- try {
- JingleCandidate candidate = new JingleCandidate(nextRandomId(), true);
- candidate.setHost(host);
- candidate.setPort(Integer.parseInt(port));
- candidate.setType(JingleCandidate.TYPE_PROXY);
- candidate.setJid(proxy);
- candidate.setPriority(655360 + 65535);
- primaryCandidates.put(account.getJid().toBareJid(),candidate);
- listener.onPrimaryCandidateFound(true,candidate);
- } catch (final NumberFormatException e) {
- listener.onPrimaryCandidateFound(false,null);
- return;
- }
- } else {
- listener.onPrimaryCandidateFound(false,null);
- }
- }
- });
- } else {
- listener.onPrimaryCandidateFound(false, null);
- }
-
- } else {
- listener.onPrimaryCandidateFound(true,
- this.primaryCandidates.get(account.getJid().toBareJid()));
- }
- }
-
- public String nextRandomId() {
- return new BigInteger(50, random).toString(32);
- }
-
- public void deliverIbbPacket(Account account, IqPacket packet) {
- String sid = null;
- Element payload = null;
- if (packet.hasChild("open", "http://jabber.org/protocol/ibb")) {
- payload = packet.findChild("open", "http://jabber.org/protocol/ibb");
- sid = payload.getAttribute("sid");
- } else if (packet.hasChild("data", "http://jabber.org/protocol/ibb")) {
- payload = packet.findChild("data", "http://jabber.org/protocol/ibb");
- sid = payload.getAttribute("sid");
- }
- if (sid != null) {
- for (JingleConnection connection : connections) {
- if (connection.getAccount() == account
- && connection.hasTransportId(sid)) {
- JingleTransport transport = connection.getTransport();
- if (transport instanceof JingleInbandTransport) {
- JingleInbandTransport inbandTransport = (JingleInbandTransport) transport;
- inbandTransport.deliverPayload(packet, payload);
- return;
- }
- }
- }
- Logging.d(Config.LOGTAG,"couldn't deliver payload: " + payload.toString());
- } else {
- Logging.d(Config.LOGTAG, "no sid found in incoming ibb packet");
- }
- }
-
- public void cancelInTransmission() {
- for (JingleConnection connection : this.connections) {
- if (connection.getJingleStatus() == JingleConnection.JINGLE_STATUS_TRANSMITTING) {
- connection.cancel();
- }
- }
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleInbandTransport.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleInbandTransport.java
deleted file mode 100644
index 84d40b3e..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleInbandTransport.java
+++ /dev/null
@@ -1,243 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-
-import android.util.Base64;
-
-import de.thedevstack.android.logcat.Logging;
-import de.thedevstack.conversationsplus.Config;
-import de.thedevstack.conversationsplus.entities.Account;
-import de.thedevstack.conversationsplus.entities.DownloadableFile;
-import de.thedevstack.conversationsplus.persistance.FileBackend;
-import de.thedevstack.conversationsplus.utils.CryptoHelper;
-import de.thedevstack.conversationsplus.utils.StreamUtil;
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xmpp.OnIqPacketReceived;
-import de.thedevstack.conversationsplus.xmpp.jid.Jid;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
-
-public class JingleInbandTransport extends JingleTransport {
-
- private Account account;
- private Jid counterpart;
- private int blockSize;
- private int seq = 0;
- private String sessionId;
-
- private boolean established = false;
-
- private boolean connected = true;
-
- private DownloadableFile file;
- private JingleConnection connection;
-
- private InputStream fileInputStream = null;
- private OutputStream fileOutputStream = null;
- private long remainingSize = 0;
- private long fileSize = 0;
- private MessageDigest digest;
-
- private OnFileTransmissionStatusChanged onFileTransmissionStatusChanged;
-
- private OnIqPacketReceived onAckReceived = new OnIqPacketReceived() {
- @Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- if (connected && packet.getType() == IqPacket.TYPE.RESULT) {
- sendNextBlock();
- }
- }
- };
-
- public JingleInbandTransport(final JingleConnection connection, final String sid, final int blocksize) {
- this.connection = connection;
- this.account = connection.getAccount();
- this.counterpart = connection.getCounterPart();
- this.blockSize = blocksize;
- this.sessionId = sid;
- }
-
- public void connect(final OnTransportConnected callback) {
- IqPacket iq = new IqPacket(IqPacket.TYPE.SET);
- iq.setTo(this.counterpart);
- Element open = iq.addChild("open", "http://jabber.org/protocol/ibb");
- open.setAttribute("sid", this.sessionId);
- open.setAttribute("stanza", "iq");
- open.setAttribute("block-size", Integer.toString(this.blockSize));
- this.connected = true;
- this.account.getXmppConnection().sendIqPacket(iq,
- new OnIqPacketReceived() {
-
- @Override
- public void onIqPacketReceived(Account account,
- IqPacket packet) {
- if (packet.getType() == IqPacket.TYPE.ERROR) {
- callback.failed();
- } else {
- callback.established();
- }
- }
- });
- }
-
- @Override
- public void receive(DownloadableFile file,
- OnFileTransmissionStatusChanged callback) {
- this.onFileTransmissionStatusChanged = callback;
- this.file = file;
- try {
- this.digest = MessageDigest.getInstance("SHA-1");
- digest.reset();
- file.getParentFile().mkdirs();
- file.createNewFile();
- this.fileOutputStream = file.createOutputStream();
- if (this.fileOutputStream == null) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": could not create output stream");
- callback.onFileTransferAborted();
- return;
- }
- this.remainingSize = this.fileSize = file.getExpectedSize();
- } catch (final NoSuchAlgorithmException | IOException e) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+" "+e.getMessage());
- callback.onFileTransferAborted();
- }
- }
-
- @Override
- public void send(DownloadableFile file,
- OnFileTransmissionStatusChanged callback) {
- this.onFileTransmissionStatusChanged = callback;
- this.file = file;
- try {
- if (this.file.getKey() != null) {
- this.remainingSize = (this.file.getSize() / 16 + 1) * 16;
- } else {
- this.remainingSize = this.file.getSize();
- }
- this.fileSize = this.remainingSize;
- this.digest = MessageDigest.getInstance("SHA-1");
- this.digest.reset();
- fileInputStream = this.file.createInputStream();
- if (fileInputStream == null) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": could no create input stream");
- callback.onFileTransferAborted();
- return;
- }
- if (this.connected) {
- this.sendNextBlock();
- }
- } catch (NoSuchAlgorithmException e) {
- callback.onFileTransferAborted();
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": "+e.getMessage());
- }
- }
-
- @Override
- public void disconnect() {
- this.connected = false;
- if (this.fileOutputStream != null) {
- try {
- this.fileOutputStream.close();
- } catch (IOException e) {
-
- }
- }
- if (this.fileInputStream != null) {
- try {
- this.fileInputStream.close();
- } catch (IOException e) {
-
- }
- }
- }
-
- private void sendNextBlock() {
- byte[] buffer = new byte[this.blockSize];
- try {
- int count = fileInputStream.read(buffer);
- if (count == -1) {
- file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
- this.onFileTransmissionStatusChanged.onFileTransmitted(file);
- fileInputStream.close();
- return;
- } else if (count != buffer.length) {
- int rem = fileInputStream.read(buffer,count,buffer.length-count);
- if (rem > 0) {
- count += rem;
- }
- }
- this.remainingSize -= count;
- this.digest.update(buffer,0,count);
- String base64 = Base64.encodeToString(buffer,0,count, Base64.NO_WRAP);
- IqPacket iq = new IqPacket(IqPacket.TYPE.SET);
- iq.setTo(this.counterpart);
- Element data = iq.addChild("data", "http://jabber.org/protocol/ibb");
- data.setAttribute("seq", Integer.toString(this.seq));
- data.setAttribute("block-size", Integer.toString(this.blockSize));
- data.setAttribute("sid", this.sessionId);
- data.setContent(base64);
- this.account.getXmppConnection().sendIqPacket(iq, this.onAckReceived);
- this.seq++;
- if (this.remainingSize > 0) {
- connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100));
- } else {
- file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
- this.onFileTransmissionStatusChanged.onFileTransmitted(file);
- fileInputStream.close();
- }
- } catch (IOException e) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": "+e.getMessage());
- StreamUtil.close(fileInputStream);
- this.onFileTransmissionStatusChanged.onFileTransferAborted();
- }
- }
-
- private void receiveNextBlock(String data) {
- try {
- byte[] buffer = Base64.decode(data, Base64.NO_WRAP);
- if (this.remainingSize < buffer.length) {
- buffer = Arrays.copyOfRange(buffer, 0, (int) this.remainingSize);
- }
- this.remainingSize -= buffer.length;
- this.fileOutputStream.write(buffer);
- this.digest.update(buffer);
- if (this.remainingSize <= 0) {
- file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
- fileOutputStream.flush();
- fileOutputStream.close();
- this.onFileTransmissionStatusChanged.onFileTransmitted(file);
- } else {
- connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100));
- }
- } catch (IOException e) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": "+e.getMessage());
- StreamUtil.close(fileOutputStream);
- this.onFileTransmissionStatusChanged.onFileTransferAborted();
- }
- }
-
- public void deliverPayload(IqPacket packet, Element payload) {
- if (payload.getName().equals("open")) {
- if (!established) {
- established = true;
- connected = true;
- this.receiveNextBlock("");
- this.account.getXmppConnection().sendIqPacket(
- packet.generateResponse(IqPacket.TYPE.RESULT), null);
- } else {
- this.account.getXmppConnection().sendIqPacket(
- packet.generateResponse(IqPacket.TYPE.ERROR), null);
- }
- } else if (connected && payload.getName().equals("data")) {
- this.receiveNextBlock(payload.getContent());
- this.account.getXmppConnection().sendIqPacket(
- packet.generateResponse(IqPacket.TYPE.RESULT), null);
- } else {
- // TODO some sort of exception
- }
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleSocks5Transport.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleSocks5Transport.java
deleted file mode 100644
index 999180c5..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleSocks5Transport.java
+++ /dev/null
@@ -1,246 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.UnknownHostException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-
-import de.thedevstack.android.logcat.Logging;
-import de.thedevstack.conversationsplus.Config;
-import de.thedevstack.conversationsplus.entities.DownloadableFile;
-import de.thedevstack.conversationsplus.persistance.FileBackend;
-import de.thedevstack.conversationsplus.utils.CryptoHelper;
-import de.thedevstack.conversationsplus.utils.StreamUtil;
-
-public class JingleSocks5Transport extends JingleTransport {
- private JingleCandidate candidate;
- private JingleConnection connection;
- private String destination;
- private OutputStream outputStream;
- private InputStream inputStream;
- private boolean isEstablished = false;
- private boolean activated = false;
- protected Socket socket;
-
- public JingleSocks5Transport(JingleConnection jingleConnection,
- JingleCandidate candidate) {
- this.candidate = candidate;
- this.connection = jingleConnection;
- try {
- MessageDigest mDigest = MessageDigest.getInstance("SHA-1");
- StringBuilder destBuilder = new StringBuilder();
- destBuilder.append(jingleConnection.getSessionId());
- if (candidate.isOurs()) {
- destBuilder.append(jingleConnection.getAccount().getJid());
- destBuilder.append(jingleConnection.getCounterPart());
- } else {
- destBuilder.append(jingleConnection.getCounterPart());
- destBuilder.append(jingleConnection.getAccount().getJid());
- }
- mDigest.reset();
- this.destination = CryptoHelper.bytesToHex(mDigest
- .digest(destBuilder.toString().getBytes()));
- } catch (NoSuchAlgorithmException e) {
-
- }
- }
-
- public void connect(final OnTransportConnected callback) {
- new Thread(new Runnable() {
-
- @Override
- public void run() {
- try {
- socket = new Socket();
- SocketAddress address = new InetSocketAddress(candidate.getHost(),candidate.getPort());
- socket.connect(address,Config.SOCKET_TIMEOUT * 1000);
- inputStream = socket.getInputStream();
- outputStream = socket.getOutputStream();
- byte[] login = { 0x05, 0x01, 0x00 };
- byte[] expectedReply = { 0x05, 0x00 };
- byte[] reply = new byte[2];
- outputStream.write(login);
- inputStream.read(reply);
- final String connect = Character.toString('\u0005')
- + '\u0001' + '\u0000' + '\u0003' + '\u0028'
- + destination + '\u0000' + '\u0000';
- if (Arrays.equals(reply, expectedReply)) {
- outputStream.write(connect.getBytes());
- byte[] result = new byte[2];
- inputStream.read(result);
- int status = result[1];
- if (status == 0) {
- isEstablished = true;
- callback.established();
- } else {
- callback.failed();
- }
- } else {
- socket.close();
- callback.failed();
- }
- } catch (UnknownHostException e) {
- callback.failed();
- } catch (IOException e) {
- callback.failed();
- }
- }
- }).start();
-
- }
-
- public void send(final DownloadableFile file,
- final OnFileTransmissionStatusChanged callback) {
- new Thread(new Runnable() {
-
- @Override
- public void run() {
- InputStream fileInputStream = null;
- try {
- MessageDigest digest = MessageDigest.getInstance("SHA-1");
- digest.reset();
- fileInputStream = file.createInputStream();
- if (fileInputStream == null) {
- Logging.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": could not create input stream");
- callback.onFileTransferAborted();
- return;
- }
- long size = file.getSize();
- long transmitted = 0;
- int count;
- byte[] buffer = new byte[8192];
- while ((count = fileInputStream.read(buffer)) > 0) {
- outputStream.write(buffer, 0, count);
- digest.update(buffer, 0, count);
- transmitted += count;
- connection.updateProgress((int) ((((double) transmitted) / size) * 100));
- }
- outputStream.flush();
- file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
- if (callback != null) {
- callback.onFileTransmitted(file);
- }
- } catch (FileNotFoundException e) {
- Logging.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage());
- callback.onFileTransferAborted();
- } catch (IOException e) {
- Logging.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage());
- callback.onFileTransferAborted();
- } catch (NoSuchAlgorithmException e) {
- Logging.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage());
- callback.onFileTransferAborted();
- } finally {
- StreamUtil.close(fileInputStream);
- }
- }
- }).start();
-
- }
-
- public void receive(final DownloadableFile file, final OnFileTransmissionStatusChanged callback) {
- new Thread(new Runnable() {
-
- @Override
- public void run() {
- OutputStream fileOutputStream = null;
- try {
- MessageDigest digest = MessageDigest.getInstance("SHA-1");
- digest.reset();
- inputStream.skip(45);
- socket.setSoTimeout(30000);
- file.getParentFile().mkdirs();
- file.createNewFile();
- fileOutputStream = file.createOutputStream();
- if (fileOutputStream == null) {
- callback.onFileTransferAborted();
- Logging.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": could not create output stream");
- return;
- }
- double size = file.getExpectedSize();
- long remainingSize = file.getExpectedSize();
- byte[] buffer = new byte[8192];
- int count = buffer.length;
- while (remainingSize > 0) {
- count = inputStream.read(buffer);
- if (count == -1) {
- callback.onFileTransferAborted();
- Logging.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": file ended prematurely with "+remainingSize+" bytes remaining");
- return;
- } else {
- fileOutputStream.write(buffer, 0, count);
- digest.update(buffer, 0, count);
- remainingSize -= count;
- }
- connection.updateProgress((int) (((size - remainingSize) / size) * 100));
- }
- fileOutputStream.flush();
- fileOutputStream.close();
- file.setSha1Sum(CryptoHelper.bytesToHex(digest.digest()));
- callback.onFileTransmitted(file);
- } catch (FileNotFoundException e) {
- Logging.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage());
- callback.onFileTransferAborted();
- } catch (IOException e) {
- Logging.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage());
- callback.onFileTransferAborted();
- } catch (NoSuchAlgorithmException e) {
- Logging.d(Config.LOGTAG, connection.getAccount().getJid().toBareJid() + ": "+e.getMessage());
- callback.onFileTransferAborted();
- } finally {
- StreamUtil.close(fileOutputStream);
- }
- }
- }).start();
- }
-
- public boolean isProxy() {
- return this.candidate.getType() == JingleCandidate.TYPE_PROXY;
- }
-
- public boolean needsActivation() {
- return (this.isProxy() && !this.activated);
- }
-
- public void disconnect() {
- if (this.outputStream != null) {
- try {
- this.outputStream.close();
- } catch (IOException e) {
-
- }
- }
- if (this.inputStream != null) {
- try {
- this.inputStream.close();
- } catch (IOException e) {
-
- }
- }
- if (this.socket != null) {
- try {
- this.socket.close();
- } catch (IOException e) {
-
- }
- }
- }
-
- public boolean isEstablished() {
- return this.isEstablished;
- }
-
- public JingleCandidate getCandidate() {
- return this.candidate;
- }
-
- public void setActivated(boolean activated) {
- this.activated = activated;
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleTransport.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleTransport.java
deleted file mode 100644
index ee0fefff..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleTransport.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle;
-
-import de.thedevstack.conversationsplus.entities.DownloadableFile;
-
-public abstract class JingleTransport {
- public abstract void connect(final OnTransportConnected callback);
-
- public abstract void receive(final DownloadableFile file,
- final OnFileTransmissionStatusChanged callback);
-
- public abstract void send(final DownloadableFile file,
- final OnFileTransmissionStatusChanged callback);
-
- public abstract void disconnect();
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnFileTransmissionStatusChanged.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnFileTransmissionStatusChanged.java
deleted file mode 100644
index 86daae81..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnFileTransmissionStatusChanged.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle;
-
-import de.thedevstack.conversationsplus.entities.DownloadableFile;
-
-public interface OnFileTransmissionStatusChanged {
- public void onFileTransmitted(DownloadableFile file);
-
- public void onFileTransferAborted();
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnJinglePacketReceived.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnJinglePacketReceived.java
deleted file mode 100644
index d6dda138..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnJinglePacketReceived.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle;
-
-import de.thedevstack.conversationsplus.entities.Account;
-import de.thedevstack.conversationsplus.xmpp.PacketReceived;
-import de.thedevstack.conversationsplus.xmpp.jingle.stanzas.JinglePacket;
-
-public interface OnJinglePacketReceived extends PacketReceived {
- public void onJinglePacketReceived(Account account, JinglePacket packet);
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnPrimaryCandidateFound.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnPrimaryCandidateFound.java
deleted file mode 100644
index be1f1d02..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnPrimaryCandidateFound.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle;
-
-public interface OnPrimaryCandidateFound {
- public void onPrimaryCandidateFound(boolean success,
- JingleCandidate canditate);
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnTransportConnected.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnTransportConnected.java
deleted file mode 100644
index 91a79a83..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/OnTransportConnected.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle;
-
-public interface OnTransportConnected {
- public void failed();
-
- public void established();
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/stanzas/Content.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/stanzas/Content.java
deleted file mode 100644
index 40eec6f1..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/stanzas/Content.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle.stanzas;
-
-import de.thedevstack.conversationsplus.entities.DownloadableFile;
-import de.thedevstack.conversationsplus.xml.Element;
-
-public class Content extends Element {
-
- private String transportId;
-
- private Content(String name) {
- super(name);
- }
-
- public Content() {
- super("content");
- }
-
- public Content(String creator, String name) {
- super("content");
- this.setAttribute("creator", creator);
- this.setAttribute("name", name);
- }
-
- public void setTransportId(String sid) {
- this.transportId = sid;
- }
-
- public void setFileOffer(DownloadableFile actualFile, boolean otr) {
- Element description = this.addChild("description",
- "urn:xmpp:jingle:apps:file-transfer:3");
- Element offer = description.addChild("offer");
- Element file = offer.addChild("file");
- file.addChild("size").setContent(Long.toString(actualFile.getSize()));
- if (otr) {
- file.addChild("name").setContent(actualFile.getName() + ".otr");
- } else {
- file.addChild("name").setContent(actualFile.getName());
- }
- }
-
- public Element getFileOffer() {
- Element description = this.findChild("description",
- "urn:xmpp:jingle:apps:file-transfer:3");
- if (description == null) {
- return null;
- }
- Element offer = description.findChild("offer");
- if (offer == null) {
- return null;
- }
- return offer.findChild("file");
- }
-
- public void setFileOffer(Element fileOffer) {
- Element description = this.findChild("description",
- "urn:xmpp:jingle:apps:file-transfer:3");
- if (description == null) {
- description = this.addChild("description",
- "urn:xmpp:jingle:apps:file-transfer:3");
- }
- description.addChild(fileOffer);
- }
-
- public String getTransportId() {
- if (hasSocks5Transport()) {
- this.transportId = socks5transport().getAttribute("sid");
- } else if (hasIbbTransport()) {
- this.transportId = ibbTransport().getAttribute("sid");
- }
- return this.transportId;
- }
-
- public Element socks5transport() {
- Element transport = this.findChild("transport",
- "urn:xmpp:jingle:transports:s5b:1");
- if (transport == null) {
- transport = this.addChild("transport",
- "urn:xmpp:jingle:transports:s5b:1");
- transport.setAttribute("sid", this.transportId);
- }
- return transport;
- }
-
- public Element ibbTransport() {
- Element transport = this.findChild("transport",
- "urn:xmpp:jingle:transports:ibb:1");
- if (transport == null) {
- transport = this.addChild("transport",
- "urn:xmpp:jingle:transports:ibb:1");
- transport.setAttribute("sid", this.transportId);
- }
- return transport;
- }
-
- public boolean hasSocks5Transport() {
- return this.hasChild("transport", "urn:xmpp:jingle:transports:s5b:1");
- }
-
- public boolean hasIbbTransport() {
- return this.hasChild("transport", "urn:xmpp:jingle:transports:ibb:1");
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/stanzas/JinglePacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/stanzas/JinglePacket.java
deleted file mode 100644
index db771a0a..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/stanzas/JinglePacket.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle.stanzas;
-
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xmpp.jid.Jid;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
-
-public class JinglePacket extends IqPacket {
- Content content = null;
- Reason reason = null;
- Element jingle = new Element("jingle");
-
- @Override
- public Element addChild(Element child) {
- if ("jingle".equals(child.getName())) {
- Element contentElement = child.findChild("content");
- if (contentElement != null) {
- this.content = new Content();
- this.content.setChildren(contentElement.getChildren());
- this.content.setAttributes(contentElement.getAttributes());
- }
- Element reasonElement = child.findChild("reason");
- if (reasonElement != null) {
- this.reason = new Reason();
- this.reason.setChildren(reasonElement.getChildren());
- this.reason.setAttributes(reasonElement.getAttributes());
- }
- this.jingle.setAttributes(child.getAttributes());
- }
- return child;
- }
-
- public JinglePacket setContent(Content content) {
- this.content = content;
- return this;
- }
-
- public Content getJingleContent() {
- if (this.content == null) {
- this.content = new Content();
- }
- return this.content;
- }
-
- public JinglePacket setReason(Reason reason) {
- this.reason = reason;
- return this;
- }
-
- public Reason getReason() {
- return this.reason;
- }
-
- private void build() {
- this.children.clear();
- this.jingle.clearChildren();
- this.jingle.setAttribute("xmlns", "urn:xmpp:jingle:1");
- if (this.content != null) {
- jingle.addChild(this.content);
- }
- if (this.reason != null) {
- jingle.addChild(this.reason);
- }
- this.children.add(jingle);
- this.setAttribute("type", "set");
- }
-
- public String getSessionId() {
- return this.jingle.getAttribute("sid");
- }
-
- public void setSessionId(String sid) {
- this.jingle.setAttribute("sid", sid);
- }
-
- @Override
- public String toString() {
- this.build();
- return super.toString();
- }
-
- public void setAction(String action) {
- this.jingle.setAttribute("action", action);
- }
-
- public String getAction() {
- return this.jingle.getAttribute("action");
- }
-
- public void setInitiator(final Jid initiator) {
- this.jingle.setAttribute("initiator", initiator.toString());
- }
-
- public boolean isAction(String action) {
- return action.equalsIgnoreCase(this.getAction());
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/stanzas/Reason.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/stanzas/Reason.java
deleted file mode 100644
index a442d8d3..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/stanzas/Reason.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.jingle.stanzas;
-
-import de.thedevstack.conversationsplus.xml.Element;
-
-public class Reason extends Element {
- private Reason(String name) {
- super(name);
- }
-
- public Reason() {
- super("reason");
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/pep/Avatar.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/pep/Avatar.java
deleted file mode 100644
index 31fda8fd..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/pep/Avatar.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.pep;
-
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xmpp.jid.Jid;
-
-import android.util.Base64;
-
-public class Avatar {
-
- public enum Origin { PEP, VCARD };
-
- public String type;
- public String sha1sum;
- public String image;
- public int height;
- public int width;
- public long size;
- public Jid owner;
- public Origin origin = Origin.PEP; //default to maintain compat
-
- public byte[] getImageAsBytes() {
- return Base64.decode(image, Base64.DEFAULT);
- }
-
- public String getFilename() {
- return sha1sum;
- }
-
- public static Avatar parseMetadata(Element items) {
- Element item = items.findChild("item");
- if (item == null) {
- return null;
- }
- Element metadata = item.findChild("metadata");
- if (metadata == null) {
- return null;
- }
- String primaryId = item.getAttribute("id");
- if (primaryId == null) {
- return null;
- }
- for (Element child : metadata.getChildren()) {
- if (child.getName().equals("info")
- && primaryId.equals(child.getAttribute("id"))) {
- Avatar avatar = new Avatar();
- String height = child.getAttribute("height");
- String width = child.getAttribute("width");
- String size = child.getAttribute("bytes");
- try {
- if (height != null) {
- avatar.height = Integer.parseInt(height);
- }
- if (width != null) {
- avatar.width = Integer.parseInt(width);
- }
- if (size != null) {
- avatar.size = Long.parseLong(size);
- }
- } catch (NumberFormatException e) {
- return null;
- }
- avatar.type = child.getAttribute("type");
- String hash = child.getAttribute("id");
- if (!isValidSHA1(hash)) {
- return null;
- }
- avatar.sha1sum = hash;
- avatar.origin = Origin.PEP;
- return avatar;
- }
- }
- return null;
- }
-
- @Override
- public boolean equals(Object object) {
- if (object != null && object instanceof Avatar) {
- Avatar other = (Avatar) object;
- return other.getFilename().equals(this.getFilename());
- } else {
- return false;
- }
- }
-
- public static Avatar parsePresence(Element x) {
- String hash = x == null ? null : x.findChildContent("photo");
- if (hash == null) {
- return null;
- }
- if (!isValidSHA1(hash)) {
- return null;
- }
- Avatar avatar = new Avatar();
- avatar.sha1sum = hash;
- avatar.origin = Origin.VCARD;
- return avatar;
- }
-
- private static boolean isValidSHA1(String s) {
- return s != null && s.matches("[a-fA-F0-9]{40}");
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacket.java
index fea1383c..961277cb 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacket.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacket.java
@@ -1,7 +1,7 @@
package de.thedevstack.conversationsplus.xmpp.pubsub;
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
+import eu.siacs.conversations.xml.Element;
+import eu.siacs.conversations.xmpp.stanzas.IqPacket;
/**
* Created by tzur on 15.01.2016.
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacketGenerator.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacketGenerator.java
index 1eb44b5e..398ec032 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacketGenerator.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacketGenerator.java
@@ -1,7 +1,7 @@
package de.thedevstack.conversationsplus.xmpp.pubsub;
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
+import eu.siacs.conversations.xml.Element;
+import eu.siacs.conversations.xmpp.stanzas.IqPacket;
/**
* Created by tzur on 15.01.2016.
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacketParser.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacketParser.java
index 682803c4..394fb5b2 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacketParser.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/pubsub/PubSubPacketParser.java
@@ -1,7 +1,7 @@
package de.thedevstack.conversationsplus.xmpp.pubsub;
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
+import eu.siacs.conversations.xml.Element;
+import eu.siacs.conversations.xmpp.stanzas.IqPacket;
/**
* Created by tzur on 15.01.2016.
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/AbstractStanza.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/AbstractStanza.java
deleted file mode 100644
index dff5b58d..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/AbstractStanza.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.stanzas;
-
-import de.thedevstack.conversationsplus.entities.Account;
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xmpp.jid.Jid;
-
-public class AbstractStanza extends Element {
-
- protected AbstractStanza(final String name) {
- super(name);
- }
-
- public Jid getTo() {
- return getAttributeAsJid("to");
- }
-
- public Jid getFrom() {
- return getAttributeAsJid("from");
- }
-
- public String getId() {
- return this.getAttribute("id");
- }
-
- public void setTo(final Jid to) {
- if (to != null) {
- setAttribute("to", to.toString());
- }
- }
-
- public void setFrom(final Jid from) {
- if (from != null) {
- setAttribute("from", from.toString());
- }
- }
-
- public void setId(final String id) {
- setAttribute("id", id);
- }
-
- public boolean fromServer(final Account account) {
- return getFrom() == null
- || getFrom().equals(account.getServer())
- || getFrom().equals(account.getJid().toBareJid())
- || getFrom().equals(account.getJid());
- }
-
- public boolean toServer(final Account account) {
- return getTo() == null
- || getTo().equals(account.getServer())
- || getTo().equals(account.getJid().toBareJid())
- || getTo().equals(account.getJid());
- }
-
- public boolean fromAccount(final Account account) {
- return getFrom() != null && getFrom().toBareJid().equals(account.getJid().toBareJid());
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacket.java
deleted file mode 100644
index fb08556b..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacket.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.stanzas;
-
-import de.thedevstack.conversationsplus.xml.Element;
-
-public class IqPacket extends AbstractStanza {
-
- public static enum TYPE {
- ERROR,
- SET,
- RESULT,
- GET,
- INVALID
- }
-
- public IqPacket(final TYPE type) {
- super("iq");
- if (type != TYPE.INVALID) {
- this.setAttribute("type", type.toString().toLowerCase());
- }
- }
-
- public IqPacket() {
- super("iq");
- }
-
- public Element query() {
- Element query = findChild("query");
- if (query == null) {
- query = addChild("query");
- }
- return query;
- }
-
- public Element query(final String xmlns) {
- final Element query = query();
- query.setAttribute("xmlns", xmlns);
- return query();
- }
-
- public TYPE getType() {
- final String type = getAttribute("type");
- switch (type) {
- case "error":
- return TYPE.ERROR;
- case "result":
- return TYPE.RESULT;
- case "set":
- return TYPE.SET;
- case "get":
- return TYPE.GET;
- default:
- return TYPE.INVALID;
- }
- }
-
- public IqPacket generateResponse(final TYPE type) {
- final IqPacket packet = new IqPacket(type);
- packet.setTo(this.getFrom());
- packet.setId(this.getId());
- return packet;
- }
-
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketGenerator.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketGenerator.java
index 27e6607f..bdf0f4b0 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketGenerator.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketGenerator.java
@@ -1,5 +1,7 @@
package de.thedevstack.conversationsplus.xmpp.stanzas;
+import eu.siacs.conversations.xmpp.stanzas.IqPacket;
+
/**
* Created by tzur on 15.01.2016.
*/
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/MessagePacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/MessagePacket.java
deleted file mode 100644
index 638ba5f4..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/MessagePacket.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.stanzas;
-
-import android.util.Pair;
-
-import java.text.ParseException;
-
-import de.thedevstack.conversationsplus.parser.AbstractParser;
-import de.thedevstack.conversationsplus.xml.Element;
-
-public class MessagePacket extends AbstractStanza {
- public static final int TYPE_CHAT = 0;
- public static final int TYPE_NORMAL = 2;
- public static final int TYPE_GROUPCHAT = 3;
- public static final int TYPE_ERROR = 4;
- public static final int TYPE_HEADLINE = 5;
-
- public MessagePacket() {
- super("message");
- }
-
- public String getBody() {
- return findChildContent("body");
- }
-
- public void setBody(String text) {
- this.children.remove(findChild("body"));
- Element body = new Element("body");
- body.setContent(text);
- this.children.add(0, body);
- }
-
- public void setType(int type) {
- switch (type) {
- case TYPE_CHAT:
- this.setAttribute("type", "chat");
- break;
- case TYPE_GROUPCHAT:
- this.setAttribute("type", "groupchat");
- break;
- case TYPE_NORMAL:
- break;
- case TYPE_ERROR:
- this.setAttribute("type","error");
- break;
- default:
- this.setAttribute("type", "chat");
- break;
- }
- }
-
- public int getType() {
- String type = getAttribute("type");
- if (type == null) {
- return TYPE_NORMAL;
- } else if (type.equals("normal")) {
- return TYPE_NORMAL;
- } else if (type.equals("chat")) {
- return TYPE_CHAT;
- } else if (type.equals("groupchat")) {
- return TYPE_GROUPCHAT;
- } else if (type.equals("error")) {
- return TYPE_ERROR;
- } else if (type.equals("headline")) {
- return TYPE_HEADLINE;
- } else {
- return TYPE_NORMAL;
- }
- }
-
- public Pair<MessagePacket,Long> getForwardedMessagePacket(String name, String namespace) {
- Element wrapper = findChild(name, namespace);
- if (wrapper == null) {
- return null;
- }
- Element forwarded = wrapper.findChild("forwarded", "urn:xmpp:forward:0");
- if (forwarded == null) {
- return null;
- }
- MessagePacket packet = create(forwarded.findChild("message"));
- if (packet == null) {
- return null;
- }
- Long timestamp = AbstractParser.getTimestamp(forwarded,null);
- return new Pair(packet,timestamp);
- }
-
- public static MessagePacket create(Element element) {
- if (element == null) {
- return null;
- }
- MessagePacket packet = new MessagePacket();
- packet.setAttributes(element.getAttributes());
- packet.setChildren(element.getChildren());
- return packet;
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/PresencePacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/PresencePacket.java
deleted file mode 100644
index dfe40f87..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/PresencePacket.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.stanzas;
-
-public class PresencePacket extends AbstractStanza {
-
- public PresencePacket() {
- super("presence");
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/ActivePacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/ActivePacket.java
deleted file mode 100644
index 47538a64..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/ActivePacket.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.stanzas.csi;
-
-import de.thedevstack.conversationsplus.xmpp.stanzas.AbstractStanza;
-
-public class ActivePacket extends AbstractStanza {
- public ActivePacket() {
- super("active");
- setAttribute("xmlns", "urn:xmpp:csi:0");
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/InactivePacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/InactivePacket.java
deleted file mode 100644
index ca5904a5..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/InactivePacket.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.stanzas.csi;
-
-import de.thedevstack.conversationsplus.xmpp.stanzas.AbstractStanza;
-
-public class InactivePacket extends AbstractStanza {
- public InactivePacket() {
- super("inactive");
- setAttribute("xmlns", "urn:xmpp:csi:0");
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/AckPacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/AckPacket.java
deleted file mode 100644
index fe1740da..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/AckPacket.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.stanzas.streammgmt;
-
-import de.thedevstack.conversationsplus.xmpp.stanzas.AbstractStanza;
-
-public class AckPacket extends AbstractStanza {
-
- public AckPacket(int sequence, int smVersion) {
- super("a");
- this.setAttribute("xmlns", "urn:xmpp:sm:" + smVersion);
- this.setAttribute("h", Integer.toString(sequence));
- }
-
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/EnablePacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/EnablePacket.java
deleted file mode 100644
index ce416f27..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/EnablePacket.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.stanzas.streammgmt;
-
-import de.thedevstack.conversationsplus.xmpp.stanzas.AbstractStanza;
-
-public class EnablePacket extends AbstractStanza {
-
- public EnablePacket(int smVersion) {
- super("enable");
- this.setAttribute("xmlns", "urn:xmpp:sm:" + smVersion);
- this.setAttribute("resume", "true");
- }
-
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/RequestPacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/RequestPacket.java
deleted file mode 100644
index eb6217ae..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/RequestPacket.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.stanzas.streammgmt;
-
-import de.thedevstack.conversationsplus.xmpp.stanzas.AbstractStanza;
-
-public class RequestPacket extends AbstractStanza {
-
- public RequestPacket(int smVersion) {
- super("r");
- this.setAttribute("xmlns", "urn:xmpp:sm:" + smVersion);
- }
-
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/ResumePacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/ResumePacket.java
deleted file mode 100644
index 90bf566e..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/streammgmt/ResumePacket.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.stanzas.streammgmt;
-
-import de.thedevstack.conversationsplus.xmpp.stanzas.AbstractStanza;
-
-public class ResumePacket extends AbstractStanza {
-
- public ResumePacket(String id, int sequence, int smVersion) {
- super("resume");
- this.setAttribute("xmlns", "urn:xmpp:sm:" + smVersion);
- this.setAttribute("previd", id);
- this.setAttribute("h", Integer.toString(sequence));
- }
-
-}