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.java72
1 files changed, 64 insertions, 8 deletions
diff --git a/src/eu/siacs/conversations/xmpp/XmppConnection.java b/src/eu/siacs/conversations/xmpp/XmppConnection.java
index ba7a9245..932b16f2 100644
--- a/src/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -31,6 +31,7 @@ import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemClock;
import android.util.Log;
+import android.util.SparseArray;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.CryptoHelper;
@@ -47,6 +48,8 @@ import eu.siacs.conversations.xmpp.stanzas.AbstractStanza;
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
+import eu.siacs.conversations.xmpp.stanzas.csi.ActivePacket;
+import eu.siacs.conversations.xmpp.stanzas.csi.InactivePacket;
import eu.siacs.conversations.xmpp.stanzas.streammgmt.AckPacket;
import eu.siacs.conversations.xmpp.stanzas.streammgmt.EnablePacket;
import eu.siacs.conversations.xmpp.stanzas.streammgmt.RequestPacket;
@@ -74,6 +77,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;
@@ -98,6 +102,7 @@ public class XmppConnection implements Runnable {
private OnMessagePacketReceived messageListener = null;
private OnStatusChanged statusListener = null;
private OnBindListener bindListener = null;
+ private OnMessageAcknowledged acknowledgedListener = null;
private MemorizingTrustManager mMemorizingTrustManager;
public XmppConnection(Account account, XmppConnectionService service) {
@@ -248,7 +253,6 @@ public class XmppConnection implements Runnable {
challange,mRandom));
tagWriter.writeElement(response);
} else if (nextTag.isStart("enabled")) {
- this.stanzasSent = 0;
Element enabled = tagReader.readElement(nextTag);
if ("true".equals(enabled.getAttribute("resume"))) {
this.streamId = enabled.getAttribute("id");
@@ -264,9 +268,27 @@ public class XmppConnection implements Runnable {
tagWriter.writeStanzaAsync(r);
} else if (nextTag.isStart("resumed")) {
lastPaketReceived = SystemClock.elapsedRealtime();
- Log.d(LOGTAG, account.getJid() + ": session resumed");
- tagReader.readElement(nextTag);
- sendPing();
+ Element resumed = tagReader.readElement(nextTag);
+ String h = resumed.getAttribute("h");
+ try {
+ int serverCount = Integer.parseInt(h);
+ if (serverCount!=stanzasSent) {
+ Log.d(LOGTAG,account.getJid() + ": session resumed with lost packages");
+ stanzasSent = serverCount;
+ } else {
+ Log.d(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));
+ }
+ }
+ }
+ messageReceipts.clear();
+ } catch (NumberFormatException e) {
+
+ }
changeStatus(Account.STATUS_ONLINE);
} else if (nextTag.isStart("r")) {
tagReader.readElement(nextTag);
@@ -276,8 +298,12 @@ public class XmppConnection implements Runnable {
Element ack = tagReader.readElement(nextTag);
lastPaketReceived = SystemClock.elapsedRealtime();
int serverSequence = Integer.parseInt(ack.getAttribute("h"));
- if (serverSequence > this.stanzasSent) {
- this.stanzasSent = serverSequence;
+ String msgId = this.messageReceipts.get(serverSequence);
+ if (msgId != null) {
+ if (this.acknowledgedListener != null) {
+ this.acknowledgedListener.onMessageAcknowledged(account, msgId);
+ }
+ this.messageReceipts.remove(serverSequence);
}
} else if (nextTag.isStart("failed")) {
tagReader.readElement(nextTag);
@@ -610,10 +636,14 @@ public class XmppConnection implements Runnable {
smVersion = 3;
EnablePacket enable = new EnablePacket(smVersion);
tagWriter.writeStanzaAsync(enable);
+ stanzasSent = 0;
+ messageReceipts.clear();
} else if (streamFeatures.hasChild("sm", "urn:xmpp:sm:2")) {
smVersion = 2;
EnablePacket enable = new EnablePacket(smVersion);
tagWriter.writeStanzaAsync(enable);
+ stanzasSent = 0;
+ messageReceipts.clear();
}
sendServiceDiscoveryInfo(account.getServer());
sendServiceDiscoveryItems(account.getServer());
@@ -751,9 +781,15 @@ public class XmppConnection implements Runnable {
private synchronized void sendPacket(final AbstractStanza packet,
PacketReceived callback) {
- // TODO dont increment stanza count if packet = request packet or ack;
- ++stanzasSent;
+ 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);
+ this.messageReceipts.put(stanzasSent, packet.getId());
+ tagWriter.writeStanzaAsync(new RequestPacket(this.smVersion));
+ }
if (callback != null) {
if (packet.getId() == null) {
packet.setId(nextRandomId());
@@ -801,6 +837,10 @@ 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);
@@ -900,6 +940,14 @@ public class XmppConnection implements Runnable {
}
}
+ public boolean csi() {
+ if (connection.streamFeatures == null) {
+ return false;
+ } else {
+ return connection.streamFeatures.hasChild("csi","urn:xmpp:csi:0");
+ }
+ }
+
public boolean pubsub() {
return hasDiscoFeature(account.getServer(), "http://jabber.org/protocol/pubsub#publish");
}
@@ -942,4 +990,12 @@ public class XmppConnection implements Runnable {
public long getLastPacketReceived() {
return this.lastPaketReceived;
}
+
+ public void sendActive() {
+ this.sendPacket(new ActivePacket(), null);
+ }
+
+ public void sendInactive() {
+ this.sendPacket(new InactivePacket(), null);
+ }
}