diff --git a/src/eu/siacs/conversations/generator/AbstractGenerator.java b/src/eu/siacs/conversations/generator/AbstractGenerator.java new file mode 100644 index 000000000..49b5d6143 --- /dev/null +++ b/src/eu/siacs/conversations/generator/AbstractGenerator.java @@ -0,0 +1,49 @@ +package eu.siacs.conversations.generator; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import android.util.Base64; + +public abstract class AbstractGenerator { + public final String[] FEATURES = { "urn:xmpp:jingle:1", + "urn:xmpp:jingle:apps:file-transfer:3", + "urn:xmpp:jingle:transports:s5b:1", + "urn:xmpp:jingle:transports:ibb:1", + "urn:xmpp:receipts", + "urn:xmpp:chat-markers:0", + "http://jabber.org/protocol/muc", + "jabber:x:conference", + "http://jabber.org/protocol/caps", + "http://jabber.org/protocol/disco#info"}; + //public final String[] FEATURES = { "http://jabber.org/protocol/muc","http://jabber.org/protocol/disco#info", "http://jabber.org/protocol/disco#items", "http://jabber.org/protocol/caps" }; + + //public final String IDENTITY_NAME = "Exodus 0.9.1"; + //public final String IDENTITY_TYPE = "pc"; + + + public final String IDENTITY_NAME = "Conversations 0.5"; + public final String IDENTITY_TYPE = "phone"; + + public String getCapHash() { + StringBuilder s = new StringBuilder(); + s.append("client/"+IDENTITY_TYPE+"//"+IDENTITY_NAME+"<"); + MessageDigest md = null; + try { + md = MessageDigest.getInstance("SHA-1"); + } + catch(NoSuchAlgorithmException e) { + return null; + } + List features = Arrays.asList(FEATURES); + Collections.sort(features); + for(String feature : features) { + s.append(feature+"<"); + } + byte[] sha1 = md.digest(s.toString().getBytes()); + return new String(Base64.encode(sha1, Base64.DEFAULT)); + } +} diff --git a/src/eu/siacs/conversations/generator/IqGenerator.java b/src/eu/siacs/conversations/generator/IqGenerator.java new file mode 100644 index 000000000..7b3350d4c --- /dev/null +++ b/src/eu/siacs/conversations/generator/IqGenerator.java @@ -0,0 +1,31 @@ +package eu.siacs.conversations.generator; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import eu.siacs.conversations.xml.Element; +import eu.siacs.conversations.xmpp.stanzas.IqPacket; + +public class IqGenerator extends AbstractGenerator { + + + + public IqPacket discoResponse(IqPacket request) { + IqPacket packet = new IqPacket(IqPacket.TYPE_RESULT); + packet.setId(request.getId()); + packet.setTo(request.getFrom()); + Element query = packet.addChild("query","http://jabber.org/protocol/disco#info"); + query.setAttribute("node", request.query().getAttribute("node")); + Element identity = query.addChild("identity"); + identity.setAttribute("category","client"); + identity.setAttribute("type", this.IDENTITY_TYPE); + identity.setAttribute("name", IDENTITY_NAME); + List features = Arrays.asList(FEATURES); + Collections.sort(features); + for(String feature : features) { + query.addChild("feature").setAttribute("var",feature); + } + return packet; + } +} diff --git a/src/eu/siacs/conversations/generator/PresenceGenerator.java b/src/eu/siacs/conversations/generator/PresenceGenerator.java index a301392ec..b34315681 100644 --- a/src/eu/siacs/conversations/generator/PresenceGenerator.java +++ b/src/eu/siacs/conversations/generator/PresenceGenerator.java @@ -2,9 +2,10 @@ package eu.siacs.conversations.generator; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; +import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.stanzas.PresencePacket; -public class PresenceGenerator { +public class PresenceGenerator extends AbstractGenerator { private PresencePacket subscription(String type, Contact contact) { PresencePacket packet = new PresencePacket(); @@ -38,6 +39,13 @@ public class PresenceGenerator { packet.addChild("status").setContent("online"); packet.addChild("x", "jabber:x:signed").setContent(sig); } + String capHash = getCapHash(); + if (capHash != null) { + Element cap = packet.addChild("c","http://jabber.org/protocol/caps"); + cap.setAttribute("hash", "sha-1"); + cap.setAttribute("node","http://conversions.siacs.eu"); + cap.setAttribute("ver", capHash); + } return packet; } } \ No newline at end of file diff --git a/src/eu/siacs/conversations/parser/IqParser.java b/src/eu/siacs/conversations/parser/IqParser.java index 049d37e1d..023fb4df3 100644 --- a/src/eu/siacs/conversations/parser/IqParser.java +++ b/src/eu/siacs/conversations/parser/IqParser.java @@ -56,23 +56,8 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { mXmppConnectionService.getJingleConnectionManager().deliverIbbPacket(account, packet); } else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) { - IqPacket iqResponse = packet - .generateRespone(IqPacket.TYPE_RESULT); - Element query = iqResponse.addChild("query", - "http://jabber.org/protocol/disco#info"); - query.addChild("feature").setAttribute("var", - "urn:xmpp:jingle:1"); - query.addChild("feature").setAttribute("var", - "urn:xmpp:jingle:apps:file-transfer:3"); - query.addChild("feature").setAttribute("var", - "urn:xmpp:jingle:transports:s5b:1"); - query.addChild("feature").setAttribute("var", - "urn:xmpp:jingle:transports:ibb:1"); - if (mXmppConnectionService.confirmMessages()) { - query.addChild("feature").setAttribute("var", - "urn:xmpp:receipts"); - } - account.getXmppConnection().sendIqPacket(iqResponse, null); + IqPacket response = mXmppConnectionService.getIqGenerator().discoResponse(packet); + account.getXmppConnection().sendIqPacket(response, null); } else { if ((packet.getType() == IqPacket.TYPE_GET) || (packet.getType() == IqPacket.TYPE_SET)) { diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java index 08930a3b3..f6cd47ee4 100644 --- a/src/eu/siacs/conversations/parser/MessageParser.java +++ b/src/eu/siacs/conversations/parser/MessageParser.java @@ -295,6 +295,8 @@ public class MessageParser extends AbstractParser implements message.markUnread(); } } + } else { + parseNormal(packet, account); } } else if (packet.getType() == MessagePacket.TYPE_GROUPCHAT) { diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index a12fb954d..155478b1b 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -29,6 +29,7 @@ import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.MucOptions.OnRenameListener; import eu.siacs.conversations.entities.Presences; +import eu.siacs.conversations.generator.IqGenerator; import eu.siacs.conversations.generator.MessageGenerator; import eu.siacs.conversations.generator.PresenceGenerator; import eu.siacs.conversations.parser.IqParser; @@ -985,6 +986,7 @@ public class XmppConnectionService extends Service { } private OnRenameListener renameListener = null; + private IqGenerator mIqGenerator = new IqGenerator(); public void setOnRenameListener(OnRenameListener listener) { this.renameListener = listener; @@ -1399,6 +1401,10 @@ public class XmppConnectionService extends Service { return this.mPresenceGenerator; } + public IqGenerator getIqGenerator() { + return this.mIqGenerator ; + } + public JingleConnectionManager getJingleConnectionManager() { return this.mJingleConnectionManager; }