aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/eu/siacs/conversations/generator/MessageGenerator.java1
-rw-r--r--src/main/java/eu/siacs/conversations/parser/MessageParser.java8
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java250
3 files changed, 127 insertions, 132 deletions
diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java
index b1a0d99d0..0f352f53e 100644
--- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java
+++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java
@@ -152,6 +152,7 @@ public class MessageGenerator extends AbstractGenerator {
packet.setFrom(account.getJid());
Element received = packet.addChild("displayed","urn:xmpp:chat-markers:0");
received.setAttribute("id", id);
+ packet.addChild("store", "urn:xmpp:hints");
return packet;
}
diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
index d8190b707..23a23b2c8 100644
--- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
@@ -304,17 +304,17 @@ public class MessageParser extends AbstractParser implements
final Jid from = packet.getFrom();
final String remoteMsgId = packet.getId();
- if (from == null || to == null) {
- Log.d(Config.LOGTAG,"no to or from in: "+packet.toString());
+ if (from == null) {
+ Log.d(Config.LOGTAG,"no from in: "+packet.toString());
return;
}
boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT;
- boolean isProperlyAddressed = !to.isBareJid() || account.countPresences() == 1;
+ boolean isProperlyAddressed = (to != null ) && (!to.isBareJid() || account.countPresences() == 1);
boolean isMucStatusMessage = from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status");
if (packet.fromAccount(account)) {
status = Message.STATUS_SEND;
- counterpart = to;
+ counterpart = to != null ? to : account.getJid();
} else {
status = Message.STATUS_RECEIVED;
counterpart = from;
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
index 978f9f60b..c64fa196d 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -357,135 +357,129 @@ public class XmppConnection implements Runnable {
}
private void processStream() 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);
- Log.e(Config.LOGTAG, String.valueOf(e));
- }
- Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": logged in");
- account.setKey(Account.PINNED_MECHANISM_KEY,
- String.valueOf(saslMechanism.getPriority()));
- tagReader.reset();
- sendStartStream();
- final Tag tag = tagReader.readTag();
- if (tag != null && tag.isStart("stream")) {
- processStream();
- } else {
- throw new IOException("server didn't restart stream after successful auth");
- }
- 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.
- Log.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");
- Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
- + ": stream managment(" + smVersion
- + ") enabled (resumable)");
- } else {
- Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
- + ": stream management(" + smVersion + ") enabled");
- }
- 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) {
- Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
- + ": session resumed with lost packages");
- stanzasSent = serverCount;
- } else {
- Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": session resumed");
- }
- acknowledgeStanzaUpTo(serverCount);
- ArrayList<AbstractAcknowledgeableStanza> failedStanzas = new ArrayList<>();
- for(int i = 0; i < this.mStanzaQueue.size(); ++i) {
- failedStanzas.add(mStanzaQueue.valueAt(i));
- }
- mStanzaQueue.clear();
- Log.d(Config.LOGTAG,"resending "+failedStanzas.size()+" stanzas");
- for(AbstractAcknowledgeableStanza packet : failedStanzas) {
- if (packet instanceof MessagePacket) {
- MessagePacket message = (MessagePacket) packet;
- mXmppConnectionService.markMessage(account,
- message.getTo().toBareJid(),
- message.getId(),
- Message.STATUS_UNSEND);
- }
- sendPacket(packet);
- }
- } catch (final NumberFormatException ignored) {
- }
- Log.d(Config.LOGTAG, account.getJid().toBareJid()+ ": online with resource " + account.getResource());
- changeStatus(Account.State.ONLINE);
- } else if (nextTag.isStart("r")) {
- tagReader.readElement(nextTag);
- if (Config.EXTENDED_SM_LOGGING) {
- Log.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"));
- acknowledgeStanzaUpTo(serverSequence);
- } catch (NumberFormatException e) {
- Log.d(Config.LOGTAG,account.getJid().toBareJid()+": server send ack without sequence number");
- }
- } else if (nextTag.isStart("failed")) {
- tagReader.readElement(nextTag);
- Log.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();
- }
- Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": last tag was " + nextTag);
- if (account.getStatus() == Account.State.ONLINE) {
- account. setStatus(Account.State.OFFLINE);
- if (statusListener != null) {
- statusListener.onStatusChanged(account);
- }
+ 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);
+ Log.e(Config.LOGTAG, String.valueOf(e));
+ }
+ Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": logged in");
+ account.setKey(Account.PINNED_MECHANISM_KEY,
+ String.valueOf(saslMechanism.getPriority()));
+ tagReader.reset();
+ sendStartStream();
+ final Tag tag = tagReader.readTag();
+ if (tag != null && tag.isStart("stream")) {
+ processStream();
+ } else {
+ throw new IOException("server didn't restart stream after successful auth");
+ }
+ 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.
+ Log.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");
+ Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
+ + ": stream managment(" + smVersion
+ + ") enabled (resumable)");
+ } else {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
+ + ": stream management(" + smVersion + ") enabled");
+ }
+ 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) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
+ + ": session resumed with lost packages");
+ stanzasSent = serverCount;
+ } else {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": session resumed");
+ }
+ acknowledgeStanzaUpTo(serverCount);
+ ArrayList<AbstractAcknowledgeableStanza> failedStanzas = new ArrayList<>();
+ for(int i = 0; i < this.mStanzaQueue.size(); ++i) {
+ failedStanzas.add(mStanzaQueue.valueAt(i));
+ }
+ mStanzaQueue.clear();
+ Log.d(Config.LOGTAG,"resending "+failedStanzas.size()+" stanzas");
+ for(AbstractAcknowledgeableStanza packet : failedStanzas) {
+ if (packet instanceof MessagePacket) {
+ MessagePacket message = (MessagePacket) packet;
+ mXmppConnectionService.markMessage(account,
+ message.getTo().toBareJid(),
+ message.getId(),
+ Message.STATUS_UNSEND);
}
+ sendPacket(packet);
+ }
+ } catch (final NumberFormatException ignored) {
+ }
+ Log.d(Config.LOGTAG, account.getJid().toBareJid()+ ": online with resource " + account.getResource());
+ changeStatus(Account.State.ONLINE);
+ } else if (nextTag.isStart("r")) {
+ tagReader.readElement(nextTag);
+ if (Config.EXTENDED_SM_LOGGING) {
+ Log.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"));
+ acknowledgeStanzaUpTo(serverSequence);
+ } catch (NumberFormatException e) {
+ Log.d(Config.LOGTAG,account.getJid().toBareJid()+": server send ack without sequence number");
+ }
+ } else if (nextTag.isStart("failed")) {
+ tagReader.readElement(nextTag);
+ Log.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();
+ }
+ throw new IOException("reached end of stream. last tag was "+nextTag);
}
private void acknowledgeStanzaUpTo(int serverCount) {