aboutsummaryrefslogtreecommitdiffstats
path: root/src/eu/siacs/conversations/xmpp/XmppConnection.java
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/eu/siacs/conversations/xmpp/XmppConnection.java204
1 files changed, 120 insertions, 84 deletions
diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java
index 932b16f2..ae6b6f72 100644
--- a/src/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -32,6 +32,7 @@ import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
import android.util.Log;
import android.util.SparseArray;
+import eu.siacs.conversations.Config;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.CryptoHelper;
@@ -58,7 +59,6 @@ import eu.siacs.conversations.xmpp.stanzas.streammgmt.ResumePacket;
public class XmppConnection implements Runnable {
protected Account account;
- private static final String LOGTAG = "xmppService";
private WakeLock wakeLock;
@@ -67,7 +67,7 @@ public class XmppConnection implements Runnable {
private Socket socket;
private XmlReader tagReader;
private TagWriter tagWriter;
-
+
private Features features = new Features(this);
private boolean shouldBind = true;
@@ -78,7 +78,7 @@ public class XmppConnection implements Runnable {
private String streamId = null;
private int smVersion = 3;
private SparseArray<String> messageReceipts = new SparseArray<String>();
-
+
private boolean usingCompression = false;
private int stanzasReceived = 0;
@@ -109,8 +109,8 @@ public class XmppConnection implements Runnable {
this.mRandom = service.getRNG();
this.mMemorizingTrustManager = service.getMemorizingTrustManager();
this.account = account;
- this.wakeLock = service.getPowerManager().newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
- account.getJid());
+ this.wakeLock = service.getPowerManager().newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, account.getJid());
tagWriter = new TagWriter();
}
@@ -133,7 +133,7 @@ public class XmppConnection implements Runnable {
}
protected void connect() {
- Log.d(LOGTAG, account.getJid() + ": connecting");
+ Log.d(Config.LOGTAG, account.getJid() + ": connecting");
usingCompression = false;
lastConnect = SystemClock.elapsedRealtime();
lastPingSent = SystemClock.elapsedRealtime();
@@ -147,7 +147,7 @@ public class XmppConnection implements Runnable {
this.changeStatus(Account.STATUS_CONNECTING);
Bundle namePort = DNSHelper.getSRVRecord(account.getServer());
if ("timeout".equals(namePort.getString("error"))) {
- Log.d(LOGTAG, account.getJid() + ": dns timeout");
+ Log.d(Config.LOGTAG, account.getJid() + ": dns timeout");
this.changeStatus(Account.STATUS_OFFLINE);
return;
}
@@ -156,13 +156,14 @@ public class XmppConnection implements Runnable {
int srvRecordPort = namePort.getInt("port");
if (srvRecordServer != null) {
if (srvIpServer != null) {
- Log.d(LOGTAG, account.getJid() + ": using values from dns "
- + srvRecordServer + "[" + srvIpServer + "]:"
- + srvRecordPort);
+ Log.d(Config.LOGTAG, account.getJid()
+ + ": using values from dns " + srvRecordServer
+ + "[" + srvIpServer + "]:" + srvRecordPort);
socket = new Socket(srvIpServer, srvRecordPort);
} else {
- Log.d(LOGTAG, account.getJid() + ": using values from dns "
- + srvRecordServer + ":" + srvRecordPort);
+ Log.d(Config.LOGTAG, account.getJid()
+ + ": using values from dns " + srvRecordServer
+ + ":" + srvRecordPort);
socket = new Socket(srvRecordServer, srvRecordPort);
}
} else {
@@ -180,7 +181,8 @@ public class XmppConnection implements Runnable {
processStream(nextTag);
break;
} else {
- Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName());
+ Log.d(Config.LOGTAG,
+ "found unexpected tag: " + nextTag.getName());
return;
}
}
@@ -190,27 +192,39 @@ public class XmppConnection implements Runnable {
} catch (UnknownHostException e) {
this.changeStatus(Account.STATUS_SERVER_NOT_FOUND);
if (wakeLock.isHeld()) {
- try { wakeLock.release();} catch (RuntimeException re) {}
+ try {
+ wakeLock.release();
+ } catch (RuntimeException re) {
+ }
}
return;
} catch (IOException e) {
this.changeStatus(Account.STATUS_OFFLINE);
if (wakeLock.isHeld()) {
- try { wakeLock.release();} catch (RuntimeException re) {}
+ try {
+ wakeLock.release();
+ } catch (RuntimeException re) {
+ }
}
return;
} catch (NoSuchAlgorithmException e) {
this.changeStatus(Account.STATUS_OFFLINE);
- Log.d(LOGTAG, "compression exception " + e.getMessage());
+ Log.d(Config.LOGTAG, "compression exception " + e.getMessage());
if (wakeLock.isHeld()) {
- try { wakeLock.release();} catch (RuntimeException re) {}
+ try {
+ wakeLock.release();
+ } catch (RuntimeException re) {
+ }
}
return;
} catch (XmlPullParserException e) {
this.changeStatus(Account.STATUS_OFFLINE);
- Log.d(LOGTAG, "xml exception " + e.getMessage());
+ Log.d(Config.LOGTAG, "xml exception " + e.getMessage());
if (wakeLock.isHeld()) {
- try { wakeLock.release();} catch (RuntimeException re) {}
+ try {
+ wakeLock.release();
+ } catch (RuntimeException re) {
+ }
}
return;
}
@@ -235,7 +249,7 @@ public class XmppConnection implements Runnable {
} else if (nextTag.isStart("compressed")) {
switchOverToZLib(nextTag);
} else if (nextTag.isStart("success")) {
- Log.d(LOGTAG, account.getJid() + ": logged in");
+ Log.d(Config.LOGTAG, account.getJid() + ": logged in");
tagReader.readTag();
tagReader.reset();
sendStartStream();
@@ -250,17 +264,18 @@ public class XmppConnection implements Runnable {
response.setAttribute("xmlns",
"urn:ietf:params:xml:ns:xmpp-sasl");
response.setContent(CryptoHelper.saslDigestMd5(account,
- challange,mRandom));
+ challange, mRandom));
tagWriter.writeElement(response);
} else if (nextTag.isStart("enabled")) {
Element enabled = tagReader.readElement(nextTag);
if ("true".equals(enabled.getAttribute("resume"))) {
this.streamId = enabled.getAttribute("id");
- Log.d(LOGTAG, account.getJid() + ": stream managment("
- + smVersion + ") enabled (resumable)");
+ Log.d(Config.LOGTAG, account.getJid()
+ + ": stream managment(" + smVersion
+ + ") enabled (resumable)");
} else {
- Log.d(LOGTAG, account.getJid() + ": stream managment("
- + smVersion + ") enabled");
+ Log.d(Config.LOGTAG, account.getJid()
+ + ": stream managment(" + smVersion + ") enabled");
}
this.lastSessionStarted = SystemClock.elapsedRealtime();
this.stanzasReceived = 0;
@@ -272,22 +287,25 @@ public class XmppConnection implements Runnable {
String h = resumed.getAttribute("h");
try {
int serverCount = Integer.parseInt(h);
- if (serverCount!=stanzasSent) {
- Log.d(LOGTAG,account.getJid() + ": session resumed with lost packages");
+ if (serverCount != stanzasSent) {
+ Log.d(Config.LOGTAG, account.getJid()
+ + ": session resumed with lost packages");
stanzasSent = serverCount;
} else {
- Log.d(LOGTAG, account.getJid() + ": session resumed");
+ Log.d(Config.LOGTAG, account.getJid()
+ + ": session resumed");
}
- if (acknowledgedListener!=null) {
- for(int i = 0; i < messageReceipts.size(); ++i) {
- if (serverCount>=messageReceipts.keyAt(i)) {
- acknowledgedListener.onMessageAcknowledged(account, messageReceipts.valueAt(i));
+ 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 (NumberFormatException e) {
-
+
}
changeStatus(Account.STATUS_ONLINE);
} else if (nextTag.isStart("r")) {
@@ -301,13 +319,14 @@ public class XmppConnection implements Runnable {
String msgId = this.messageReceipts.get(serverSequence);
if (msgId != null) {
if (this.acknowledgedListener != null) {
- this.acknowledgedListener.onMessageAcknowledged(account, msgId);
+ this.acknowledgedListener.onMessageAcknowledged(
+ account, msgId);
}
this.messageReceipts.remove(serverSequence);
}
} else if (nextTag.isStart("failed")) {
tagReader.readElement(nextTag);
- Log.d(LOGTAG, account.getJid() + ": resumption failed");
+ Log.d(Config.LOGTAG, account.getJid() + ": resumption failed");
streamId = null;
if (account.getStatus() != Account.STATUS_ONLINE) {
sendBindRequest();
@@ -347,7 +366,7 @@ public class XmppConnection implements Runnable {
}
element.setAttributes(currentTag.getAttributes());
Tag nextTag = tagReader.readTag();
- if (nextTag==null) {
+ if (nextTag == null) {
throw new IOException("interrupted mid tag");
}
while (!nextTag.isEnd(element.getName())) {
@@ -361,7 +380,7 @@ public class XmppConnection implements Runnable {
element.addChild(child);
}
nextTag = tagReader.readTag();
- if (nextTag==null) {
+ if (nextTag == null) {
throw new IOException("interrupted mid tag");
}
}
@@ -446,7 +465,7 @@ public class XmppConnection implements Runnable {
.setInputStream(new ZLibInputStream(tagReader.getInputStream()));
sendStartStream();
- Log.d(LOGTAG, account.getJid() + ": compression enabled");
+ Log.d(Config.LOGTAG, account.getJid() + ": compression enabled");
usingCompression = true;
processStream(tagReader.readTag());
}
@@ -462,23 +481,30 @@ public class XmppConnection implements Runnable {
tagReader.readTag();
try {
SSLContext sc = SSLContext.getInstance("TLS");
- sc.init(null, new X509TrustManager[] { this.mMemorizingTrustManager }, mRandom);
+ sc.init(null,
+ new X509TrustManager[] { this.mMemorizingTrustManager },
+ mRandom);
SSLSocketFactory factory = sc.getSocketFactory();
-
- HostnameVerifier verifier = this.mMemorizingTrustManager.wrapHostnameVerifier(new org.apache.http.conn.ssl.StrictHostnameVerifier());
+
+ HostnameVerifier verifier = this.mMemorizingTrustManager
+ .wrapHostnameVerifier(new org.apache.http.conn.ssl.StrictHostnameVerifier());
SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket,
socket.getInetAddress().getHostAddress(), socket.getPort(),
true);
-
- if (verifier != null && !verifier.verify(account.getServer(), sslSocket.getSession())) {
- Log.d(LOGTAG, account.getJid() + ": host mismatch in TLS connection");
+
+ if (verifier != null
+ && !verifier.verify(account.getServer(),
+ sslSocket.getSession())) {
+ Log.d(Config.LOGTAG, account.getJid()
+ + ": host mismatch in TLS connection");
sslSocket.close();
throw new IOException();
}
tagReader.setInputStream(sslSocket.getInputStream());
tagWriter.setOutputStream(sslSocket.getOutputStream());
sendStartStream();
- Log.d(LOGTAG, account.getJid() + ": TLS connection established");
+ Log.d(Config.LOGTAG, account.getJid()
+ + ": TLS connection established");
processStream(tagReader.readTag());
sslSocket.close();
} catch (NoSuchAlgorithmException e1) {
@@ -604,7 +630,7 @@ public class XmppConnection implements Runnable {
changeStatus(Account.STATUS_REGISTRATION_CONFLICT);
} else {
changeStatus(Account.STATUS_REGISTRATION_FAILED);
- Log.d(LOGTAG, packet.toString());
+ Log.d(Config.LOGTAG, packet.toString());
}
disconnect(true);
}
@@ -612,7 +638,7 @@ public class XmppConnection implements Runnable {
} else {
changeStatus(Account.STATUS_REGISTRATION_FAILED);
disconnect(true);
- Log.d(LOGTAG, account.getJid()
+ Log.d(Config.LOGTAG, account.getJid()
+ ": could not register. instructions are"
+ instructions.getContent());
}
@@ -628,9 +654,9 @@ public class XmppConnection implements Runnable {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
Element bind = packet.findChild("bind");
- if (bind!=null) {
+ if (bind != null) {
Element jid = bind.findChild("jid");
- if (jid!=null) {
+ if (jid != null) {
account.setResource(jid.getContent().split("/")[1]);
if (streamFeatures.hasChild("sm", "urn:xmpp:sm:3")) {
smVersion = 3;
@@ -638,7 +664,8 @@ public class XmppConnection implements Runnable {
tagWriter.writeStanzaAsync(enable);
stanzasSent = 0;
messageReceipts.clear();
- } else if (streamFeatures.hasChild("sm", "urn:xmpp:sm:2")) {
+ } else if (streamFeatures.hasChild("sm",
+ "urn:xmpp:sm:2")) {
smVersion = 2;
EnablePacket enable = new EnablePacket(smVersion);
tagWriter.writeStanzaAsync(enable);
@@ -660,7 +687,8 @@ public class XmppConnection implements Runnable {
}
});
if (this.streamFeatures.hasChild("session")) {
- Log.d(LOGTAG, account.getJid() + ": sending deprecated session");
+ Log.d(Config.LOGTAG, account.getJid()
+ + ": sending deprecated session");
IqPacket startSession = new IqPacket(IqPacket.TYPE_SET);
startSession.addChild("session",
"urn:ietf:params:xml:ns:xmpp-session");
@@ -725,10 +753,10 @@ public class XmppConnection implements Runnable {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
if (!packet.hasChild("error")) {
- Log.d(LOGTAG, account.getJid()
+ Log.d(Config.LOGTAG, account.getJid()
+ ": successfully enabled carbons");
} else {
- Log.d(LOGTAG, account.getJid()
+ Log.d(Config.LOGTAG, account.getJid()
+ ": error enableing carbons " + packet.toString());
}
}
@@ -736,7 +764,7 @@ public class XmppConnection implements Runnable {
}
private void processStreamError(Tag currentTag) {
- Log.d(LOGTAG, "processStreamError");
+ Log.d(Config.LOGTAG, "processStreamError");
}
private void sendStartStream() throws IOException {
@@ -778,15 +806,18 @@ public class XmppConnection implements Runnable {
public void sendPresencePacket(PresencePacket packet) {
this.sendPacket(packet, null);
}
-
+
private synchronized void sendPacket(final AbstractStanza packet,
PacketReceived callback) {
- if (packet.getName().equals("iq") || packet.getName().equals("message") || packet.getName().equals("presence")) {
+ if (packet.getName().equals("iq") || packet.getName().equals("message")
+ || packet.getName().equals("presence")) {
++stanzasSent;
}
tagWriter.writeStanzaAsync(packet);
- if (packet instanceof MessagePacket && packet.getId() != null && this.streamId != null) {
- Log.d(LOGTAG,"request delivery report for stanza "+stanzasSent);
+ if (packet instanceof MessagePacket && packet.getId() != null
+ && this.streamId != null) {
+ Log.d(Config.LOGTAG, "request delivery report for stanza "
+ + stanzasSent);
this.messageReceipts.put(stanzasSent, packet.getId());
tagWriter.writeStanzaAsync(new RequestPacket(this.smVersion));
}
@@ -837,14 +868,14 @@ public class XmppConnection implements Runnable {
public void setOnBindListener(OnBindListener listener) {
this.bindListener = listener;
}
-
+
public void setOnMessageAcknowledgeListener(OnMessageAcknowledged listener) {
this.acknowledgedListener = listener;
}
public void disconnect(boolean force) {
changeStatus(Account.STATUS_OFFLINE);
- Log.d(LOGTAG, "disconnecting");
+ Log.d(Config.LOGTAG, "disconnecting");
try {
if (force) {
socket.close();
@@ -858,20 +889,21 @@ public class XmppConnection implements Runnable {
tagWriter.finish();
try {
while (!tagWriter.finished()) {
- Log.d(LOGTAG, "not yet finished");
+ Log.d(Config.LOGTAG, "not yet finished");
Thread.sleep(100);
}
tagWriter.writeTag(Tag.end("stream:stream"));
} catch (IOException e) {
- Log.d(LOGTAG, "io exception during disconnect");
+ Log.d(Config.LOGTAG,
+ "io exception during disconnect");
} catch (InterruptedException e) {
- Log.d(LOGTAG, "interrupted");
+ Log.d(Config.LOGTAG, "interrupted");
}
}
}
}).start();
} catch (IOException e) {
- Log.d(LOGTAG, "io exception during disconnect");
+ Log.d(Config.LOGTAG, "io exception during disconnect");
}
}
@@ -884,10 +916,10 @@ public class XmppConnection implements Runnable {
}
return items;
}
-
+
public String findDiscoItemByFeature(String feature) {
List<String> items = findDiscoItemsByFeature(feature);
- if (items.size()>=1) {
+ if (items.size() >= 1) {
return items.get(0);
}
return null;
@@ -896,7 +928,7 @@ public class XmppConnection implements Runnable {
public void r() {
this.tagWriter.writeStanzaAsync(new RequestPacket(smVersion));
}
-
+
public String getMucServer() {
return findDiscoItemByFeature("http://jabber.org/protocol/muc");
}
@@ -910,28 +942,29 @@ public class XmppConnection implements Runnable {
public int getAttempt() {
return this.attempt;
}
-
+
public Features getFeatures() {
return this.features;
}
-
+
public class Features {
XmppConnection connection;
+
public Features(XmppConnection connection) {
this.connection = connection;
}
-
+
private boolean hasDiscoFeature(String server, String feature) {
if (!connection.disco.containsKey(server)) {
return false;
}
return connection.disco.get(server).contains(feature);
}
-
+
public boolean carbons() {
return hasDiscoFeature(account.getServer(), "urn:xmpp:carbons:2");
}
-
+
public boolean sm() {
if (connection.streamFeatures == null) {
return false;
@@ -939,19 +972,21 @@ public class XmppConnection implements Runnable {
return connection.streamFeatures.hasChild("sm");
}
}
-
+
public boolean csi() {
if (connection.streamFeatures == null) {
return false;
} else {
- return connection.streamFeatures.hasChild("csi","urn:xmpp:csi:0");
+ return connection.streamFeatures.hasChild("csi",
+ "urn:xmpp:csi:0");
}
}
-
+
public boolean pubsub() {
- return hasDiscoFeature(account.getServer(), "http://jabber.org/protocol/pubsub#publish");
+ return hasDiscoFeature(account.getServer(),
+ "http://jabber.org/protocol/pubsub#publish");
}
-
+
public boolean rosterVersioning() {
if (connection.streamFeatures == null) {
return false;
@@ -959,11 +994,12 @@ public class XmppConnection implements Runnable {
return connection.streamFeatures.hasChild("ver");
}
}
-
+
public boolean streamhost() {
- return connection.findDiscoItemByFeature("http://jabber.org/protocol/bytestreams") != null;
+ return connection
+ .findDiscoItemByFeature("http://jabber.org/protocol/bytestreams") != null;
}
-
+
public boolean compression() {
return connection.usingCompression;
}
@@ -978,15 +1014,15 @@ public class XmppConnection implements Runnable {
}
return System.currentTimeMillis() - diff;
}
-
+
public long getLastConnect() {
return this.lastConnect;
}
-
+
public long getLastPingSent() {
return this.lastPingSent;
}
-
+
public long getLastPacketReceived() {
return this.lastPaketReceived;
}
@@ -994,7 +1030,7 @@ public class XmppConnection implements Runnable {
public void sendActive() {
this.sendPacket(new ActivePacket(), null);
}
-
+
public void sendInactive() {
this.sendPacket(new InactivePacket(), null);
}