aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/xmpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs/conversations/xmpp')
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java97
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java10
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java4
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java17
4 files changed, 82 insertions, 46 deletions
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
index b8e25d4b..0b6bb15b 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -90,7 +90,7 @@ public class XmppConnection implements Runnable {
private boolean shouldBind = true;
private boolean shouldAuthenticate = true;
private Element streamFeatures;
- private final HashMap<String, List<String>> disco = new HashMap<>();
+ private final HashMap<Jid, Info> disco = new HashMap<>();
private String streamId = null;
private int smVersion = 3;
@@ -334,16 +334,23 @@ public class XmppConnection implements Runnable {
} 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) {
+ 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();
final int serverSequence = Integer.parseInt(ack.getAttribute("h"));
+ if (Config.EXTENDED_SM_LOGGING) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server acknowledged stanza #" + serverSequence);
+ }
final String msgId = this.messageReceipts.get(serverSequence);
if (msgId != null) {
if (this.acknowledgedListener != null) {
@@ -597,8 +604,10 @@ public class XmppConnection implements Runnable {
} else if (this.streamFeatures.hasChild("sm", "urn:xmpp:sm:"
+ smVersion)
&& streamId != null) {
- final ResumePacket resume = new ResumePacket(this.streamId,
- stanzasReceived, smVersion);
+ if (Config.EXTENDED_SM_LOGGING) {
+ Log.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();
@@ -734,6 +743,7 @@ public class XmppConnection implements Runnable {
features.blockListRequested = false;
disco.clear();
sendServiceDiscoveryInfo(account.getServer());
+ sendServiceDiscoveryInfo(account.getJid().toBareJid());
sendServiceDiscoveryItems(account.getServer());
if (bindListener != null) {
bindListener.onBind(account);
@@ -741,34 +751,35 @@ public class XmppConnection implements Runnable {
sendInitialPing();
}
- private void sendServiceDiscoveryInfo(final Jid server) {
- if (disco.containsKey(server.toDomainJid().toString())) {
- if (account.getServer().equals(server.toDomainJid())) {
+ 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(server.toDomainJid());
+ 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 List<String> features = new ArrayList<>();
+ final Info info = new Info();
for (final Element element : elements) {
if (element.getName().equals("identity")) {
- if ("irc".equals(element.getAttribute("type"))) {
- //add fake feature to not confuse irc and real muc
- features.add("siacs:no:muc");
+ 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")) {
- features.add(element.getAttribute("var"));
+ info.features.add(element.getAttribute("var"));
}
}
- disco.put(server.toDomainJid().toString(), features);
+ disco.put(jid, info);
- if (account.getServer().equals(server.toDomainJid())) {
+ if (account.getServer().equals(jid)) {
enableAdvancedStreamFeatures();
for (final OnAdvancedStreamFeaturesLoaded listener : advancedStreamFeaturesLoadedListeners) {
listener.onAdvancedStreamFeaturesAvailable(account);
@@ -784,7 +795,7 @@ public class XmppConnection implements Runnable {
sendEnableCarbons();
}
if (getFeatures().blocking() && !features.blockListRequested) {
- Log.d(Config.LOGTAG, "Requesting block list");
+ Log.d(Config.LOGTAG,account.getJid().toBareJid()+": Requesting block list");
this.sendIqPacket(getIqGenerator().generateGetBlockList(), mXmppConnectionService.getIqParser());
}
}
@@ -891,7 +902,9 @@ public class XmppConnection implements Runnable {
}
tagWriter.writeStanzaAsync(packet);
if (packet instanceof MessagePacket && packet.getId() != null && this.streamId != null) {
- Log.d(Config.LOGTAG, "request delivery report for stanza " + stanzasSent);
+ if (Config.EXTENDED_SM_LOGGING) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": requesting ack for message stanza #" + stanzasSent);
+ }
this.messageReceipts.put(stanzasSent, packet.getId());
tagWriter.writeStanzaAsync(new RequestPacket(this.smVersion));
}
@@ -981,11 +994,15 @@ public class XmppConnection implements Runnable {
}
}
+ public void resetStreamId() {
+ this.streamId = null;
+ }
+
public List<String> findDiscoItemsByFeature(final String feature) {
final List<String> items = new ArrayList<>();
- for (final Entry<String, List<String>> cursor : disco.entrySet()) {
- if (cursor.getValue().contains(feature)) {
- items.add(cursor.getKey());
+ for (final Entry<Jid, Info> cursor : disco.entrySet()) {
+ if (cursor.getValue().features.contains(feature)) {
+ items.add(cursor.getKey().toString());
}
}
return items;
@@ -1004,10 +1021,12 @@ public class XmppConnection implements Runnable {
}
public String getMucServer() {
- for (final Entry<String, List<String>> cursor : disco.entrySet()) {
- final List<String> value = cursor.getValue();
- if (value.contains("http://jabber.org/protocol/muc") && !value.contains("jabber:iq:gateway") && !value.contains("siacs:no:muc")) {
- return cursor.getKey();
+ 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;
@@ -1062,6 +1081,11 @@ public class XmppConnection implements Runnable {
this.lastConnect = 0;
}
+ private class Info {
+ public final ArrayList<String> features = new ArrayList<>();
+ public final ArrayList<Pair<String,String>> identities = new ArrayList<>();
+ }
+
public class Features {
XmppConnection connection;
private boolean carbonsEnabled = false;
@@ -1073,8 +1097,8 @@ public class XmppConnection implements Runnable {
}
private boolean hasDiscoFeature(final Jid server, final String feature) {
- return connection.disco.containsKey(server.toDomainJid().toString()) &&
- connection.disco.get(server.toDomainJid().toString()).contains(feature);
+ return connection.disco.containsKey(server) &&
+ connection.disco.get(server).features.contains(feature);
}
public boolean carbons() {
@@ -1090,24 +1114,35 @@ public class XmppConnection implements Runnable {
}
public boolean sm() {
- return streamId != null;
+ 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 pubsub() {
- return hasDiscoFeature(account.getServer(),
- "http://jabber.org/protocol/pubsub#publish");
+ 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() {
- return hasDiscoFeature(account.getServer(), "urn:xmpp:mam:0");
+ 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().toString());
+ return disco.containsKey(account.getServer());
}
public boolean rosterVersioning() {
diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
index 2d949e21..e448f947 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java
@@ -192,7 +192,7 @@ public class JingleConnection implements Downloadable {
} else {
response = packet.generateResponse(IqPacket.TYPE.ERROR);
}
- account.getXmppConnection().sendIqPacket(response, null);
+ mXmppConnectionService.sendIqPacket(account,response,null);
}
public void init(Message message) {
@@ -317,7 +317,7 @@ public class JingleConnection implements Downloadable {
message.setBody(Long.toString(size));
conversation.add(message);
mXmppConnectionService.updateConversationUi();
- if (size <= this.mJingleConnectionManager
+ if (size < this.mJingleConnectionManager
.getAutoAcceptFileSize()) {
Log.d(Config.LOGTAG, "auto accepting file from "
+ packet.getFrom());
@@ -459,11 +459,11 @@ public class JingleConnection implements Downloadable {
}
private void sendJinglePacket(JinglePacket packet) {
- account.getXmppConnection().sendIqPacket(packet, responseListener);
+ mXmppConnectionService.sendIqPacket(account,packet,responseListener);
}
private void sendJinglePacket(JinglePacket packet, OnIqPacketReceived callback) {
- account.getXmppConnection().sendIqPacket(packet,callback);
+ mXmppConnectionService.sendIqPacket(account,packet,callback);
}
private boolean receiveAccept(JinglePacket packet) {
@@ -556,7 +556,7 @@ public class JingleConnection implements Downloadable {
.setAttribute("sid", this.getSessionId());
activation.query().addChild("activate")
.setContent(this.getCounterPart().toString());
- this.account.getXmppConnection().sendIqPacket(activation,
+ mXmppConnectionService.sendIqPacket(account,activation,
new OnIqPacketReceived() {
@Override
diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java
index 174f70fa..9866af03 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleInbandTransport.java
@@ -11,6 +11,7 @@ import android.util.Base64;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.DownloadableFile;
+import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
@@ -172,6 +173,7 @@ public class JingleInbandTransport extends JingleTransport {
connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100));
}
} catch (IOException e) {
+ FileBackend.close(fileInputStream);
this.onFileTransmissionStatusChanged.onFileTransferAborted();
}
}
@@ -198,6 +200,7 @@ public class JingleInbandTransport extends JingleTransport {
connection.updateProgress((int) ((((double) (this.fileSize - this.remainingSize)) / this.fileSize) * 100));
}
} catch (IOException e) {
+ FileBackend.close(fileOutputStream);
this.onFileTransmissionStatusChanged.onFileTransferAborted();
}
}
@@ -207,6 +210,7 @@ public class JingleInbandTransport extends JingleTransport {
if (!established) {
established = true;
connected = true;
+ this.receiveNextBlock("");
this.account.getXmppConnection().sendIqPacket(
packet.generateResponse(IqPacket.TYPE.RESULT), null);
} else {
diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java
index c3419580..72015a05 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java
@@ -11,6 +11,7 @@ import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import eu.siacs.conversations.entities.DownloadableFile;
+import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.utils.CryptoHelper;
public class JingleSocks5Transport extends JingleTransport {
@@ -126,25 +127,19 @@ public class JingleSocks5Transport extends JingleTransport {
} catch (NoSuchAlgorithmException e) {
callback.onFileTransferAborted();
} finally {
- try {
- if (fileInputStream != null) {
- fileInputStream.close();
- }
- } catch (IOException e) {
- callback.onFileTransferAborted();
- }
+ FileBackend.close(fileInputStream);
}
}
}).start();
}
- public void receive(final DownloadableFile file,
- final OnFileTransmissionStatusChanged callback) {
+ 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();
@@ -152,7 +147,7 @@ public class JingleSocks5Transport extends JingleTransport {
socket.setSoTimeout(30000);
file.getParentFile().mkdirs();
file.createNewFile();
- OutputStream fileOutputStream = file.createOutputStream();
+ fileOutputStream = file.createOutputStream();
if (fileOutputStream == null) {
callback.onFileTransferAborted();
return;
@@ -183,6 +178,8 @@ public class JingleSocks5Transport extends JingleTransport {
callback.onFileTransferAborted();
} catch (NoSuchAlgorithmException e) {
callback.onFileTransferAborted();
+ } finally {
+ FileBackend.close(fileOutputStream);
}
}
}).start();