diff options
author | Daniel Gultsch <daniel@gultsch.de> | 2015-04-25 18:24:10 +0200 |
---|---|---|
committer | Daniel Gultsch <daniel@gultsch.de> | 2015-04-25 18:24:10 +0200 |
commit | 5ea1c547d5d956473d3bce83d1f4354c0936ac6f (patch) | |
tree | 0ba6b659e5608b0dbebe6ddb5b0d2b6248fa537c /src/main/java/eu/siacs/conversations/xmpp | |
parent | 82daf849aa9b68dbd61f61923d8d618630af50bf (diff) |
fixed service discovery by properly storing and checking identities
Diffstat (limited to '')
-rw-r--r-- | src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 75 |
1 files changed, 48 insertions, 27 deletions
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 1351226b..cf580df1 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,6 +334,7 @@ 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")) { @@ -734,6 +735,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 +743,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); @@ -987,9 +990,9 @@ public class XmppConnection implements Runnable { 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; @@ -1008,10 +1011,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; @@ -1066,6 +1071,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; @@ -1077,8 +1087,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() { @@ -1094,24 +1104,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() { |