Complete XEP-0115. see #286
Your capability is now calculate and send in each presence stanza.
Still needs to use a disk cache to store the capabilities.
--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java Thu Jul 22 23:34:36 2010 +0200
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java Mon Jul 26 01:21:28 2010 +0200
@@ -388,6 +388,8 @@
* enregistre les features dispo dans notre version Liste de features que Telepathy supporte.
*/
private void initFeatures() {
+ ServiceDiscoveryManager.setIdentityName("Beem");
+ ServiceDiscoveryManager.setIdentityType("phone");
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(mAdaptee);
if (sdm == null)
sdm = new ServiceDiscoveryManager(mAdaptee);
@@ -396,6 +398,7 @@
sdm.addFeature("http://jabber.org/protocol/caps");
mChatStateManager = ChatStateManager.getInstance(mAdaptee);
CapsManager caps = new CapsManager(sdm, mAdaptee);
+ caps.setNode("http://www.beem-project.com");
}
/**
--- a/src/com/beem/project/beem/smack/caps/CapsExtension.java Thu Jul 22 23:34:36 2010 +0200
+++ b/src/com/beem/project/beem/smack/caps/CapsExtension.java Mon Jul 26 01:21:28 2010 +0200
@@ -1,7 +1,57 @@
+/*
+ BEEM is a videoconference application on the Android Platform.
+
+ Copyright (C) 2009 by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ This file is part of BEEM.
+
+ BEEM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ BEEM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BEEM. If not, see <http://www.gnu.org/licenses/>.
+
+ Please send bug reports with examples or suggestions to
+ contact@beem-project.com or http://dev.beem-project.com/
+
+ Epitech, hereby disclaims all copyright interest in the program "Beem"
+ written by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ Nicolas Sadirac, November 26, 2009
+ President of Epitech.
+
+ Flavien Astraud, November 26, 2009
+ Head of the EIP Laboratory.
+
+*/
+
package com.beem.project.beem.smack.caps;
import org.jivesoftware.smack.packet.PacketExtension;
+/**
+ * This extension represents a capability of XEP-0115.
+ *
+ * @author Frédéric Barthéléry
+ * @version $Revision$
+ */
public class CapsExtension implements PacketExtension {
private String mVer;
@@ -10,69 +60,117 @@
private String mExt;
- public CapsExtension(String hash, String node, String ver) {
+ /**
+ * Create a CapsExtension.
+ *
+ * @param hash The value of the hash attribute.
+ * @param node the value of the node attribute
+ * @param ver the value of the ver attribute.
+ */
+ public CapsExtension(final String hash, final String node, final String ver) {
mHash = hash;
mNode = node;
mVer = ver;
}
- public String getVer(){
+ /**
+ * Get the ver attribute value.
+ *
+ * @return the value of the ver attribute.
+ */
+ public String getVer() {
return mVer;
}
- public String getHash(){
+ /**
+ * Get the hash attribute value.
+ *
+ * @return the value of the hash attribute.
+ */
+ public String getHash() {
return mHash;
}
- public String getNode(){
+ /**
+ * Get the node attribute value.
+ *
+ * @return the value of the node attribute.
+ */
+ public String getNode() {
return mNode;
}
- public String getExt(){
+ /**
+ * Get the ext attribute value.
+ *
+ * @return the value of the ext attribute.
+ */
+ public String getExt() {
return mExt;
}
+ /**
+ * Set the hash attribute.
+ *
+ * @param hash the value of hash
+ */
public void setHash(String hash) {
mHash = hash;
}
+ /**
+ * Set the ver attribute.
+ *
+ * @param ver the value of ver
+ */
public void setVer(String ver) {
mVer = ver;
}
+ /**
+ * Set the node attribute.
+ *
+ * @param node the value of node
+ */
public void setNode(String node) {
mNode = node;
}
+ /**
+ * Set the ext attribute.
+ *
+ * @param ext the value of ext
+ */
public void setExt(String ext) {
mExt = ext;
}
@Override
- public String getElementName() {
+ public String getElementName() {
return "c";
- }
+ }
+
+ @Override
+ public String getNamespace() {
+ return "http://jabber.org/protocol/caps";
+ }
@Override
- public String getNamespace() {
- return "http://jabber.org/protocol/caps";
- }
-
- @Override
- public String toXML(){
- StringBuilder b = new StringBuilder("<");
- b.append(getElementName());
- b.append(" xmlns=\"").append(getNamespace()).append("\" ");
- if (mHash != null){
- b.append("hash=\"").append(mHash).append("\" ");
- }
- if (mNode != null)
- b.append("node=\"").append(mNode).append("\" ");
- if (mVer != null)
- b.append("ver=\"").append(mVer).append("\" ");
- if (mExt!= null)
- b.append("ext=\"").append(mExt).append("\" ");
- b.append("/>");
- return b.toString();
- }
+ public String toXML() {
+ StringBuilder b = new StringBuilder("<");
+ b.append(getElementName());
+ b.append(" xmlns=\"").append(getNamespace()).append("\" ");
+ if (mHash != null) {
+ b.append("hash=\"").append(mHash).append("\" ");
+ }
+ if (mNode != null)
+ b.append("node=\"").append(mNode).append("\" ");
+ if (mVer != null)
+ b.append("ver=\"").append(mVer).append("\" ");
+ if (mExt != null)
+ b.append("ext=\"").append(mExt).append("\" ");
+ b.append("/>");
+ return b.toString();
+ }
+
}
--- a/src/com/beem/project/beem/smack/caps/CapsManager.java Thu Jul 22 23:34:36 2010 +0200
+++ b/src/com/beem/project/beem/smack/caps/CapsManager.java Mon Jul 26 01:21:28 2010 +0200
@@ -1,15 +1,60 @@
+/*
+ BEEM is a videoconference application on the Android Platform.
+ Copyright (C) 2009 by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ This file is part of BEEM.
+
+ BEEM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ BEEM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BEEM. If not, see <http://www.gnu.org/licenses/>.
+
+ Please send bug reports with examples or suggestions to
+ contact@beem-project.com or http://dev.beem-project.com/
+
+ Epitech, hereby disclaims all copyright interest in the program "Beem"
+ written by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ Nicolas Sadirac, November 26, 2009
+ President of Epitech.
+
+ Flavien Astraud, November 26, 2009
+ Head of the EIP Laboratory.
+
+*/
package com.beem.project.beem.smack.caps;
import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smack.PacketInterceptor;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.packet.DiscoverInfo;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension;
+import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smack.util.collections.ReferenceMap;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.filter.PacketExtensionFilter;
import java.util.Map;
@@ -23,25 +68,41 @@
import org.jivesoftware.smack.util.StringUtils;
+/**
+ * Capabilities manager to implements XEP-0115.
+ *
+ * @author Frédéric Barthéléry
+ * @version $Revision$
+ */
public class CapsManager {
// the verCache should be stored on disk
- Map<String, DiscoverInfo> mVerCache = new ReferenceMap<String, DiscoverInfo>();
- Map<String, DiscoverInfo> mJidCache = new ReferenceMap<String, DiscoverInfo>();
+ private Map<String, DiscoverInfo> mVerCache = new ReferenceMap<String, DiscoverInfo>();
+ private Map<String, DiscoverInfo> mJidCache = new ReferenceMap<String, DiscoverInfo>();
private ServiceDiscoveryManager mSdm;
private Connection mConnection;
+ private String mNode;
private List<String> mSupportedAlgorithm = new ArrayList<String>();
- public CapsManager(ServiceDiscoveryManager sdm, Connection conn) {
+ /**
+ * Create a CapsManager.
+ *
+ * @param sdm The service discovery manager to use.
+ * @param conn The connection to manage.
+ */
+ public CapsManager(final ServiceDiscoveryManager sdm, final Connection conn) {
mSdm = sdm;
mConnection = conn;
init();
}
+ /**
+ * Initialize this CapsManageer.
+ */
private void init() {
initSupportedAlgorithm();
PacketFilter filter = new PacketExtensionFilter("c", "http://jabber.org/protocol/caps");
- mConnection.addPacketListener( new PacketListener() {
+ mConnection.addPacketListener(new PacketListener() {
public void processPacket(Packet packet) {
PacketExtension p = packet.getExtension("c", "http://jabber.org/protocol/caps");
CapsExtension caps = (CapsExtension) p;
@@ -49,12 +110,41 @@
validate(packet.getFrom(), caps.getVer(), caps.getHash());
}
}, filter);
+ mConnection.addPacketInterceptor(new PacketInterceptor() {
+
+ public void interceptPacket(Packet packet) {
+ DiscoverInfo info = getOwnInformation();
+ if (mSupportedAlgorithm.size() > 0) {
+ try {
+ String algo = mSupportedAlgorithm.get(0);
+ String ver = calculateVer(info, algo);
+ CapsExtension caps = new CapsExtension(algo, mNode, ver);
+ packet.addExtension(caps);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }, new PacketTypeFilter(Presence.class));
}
+ /**
+ * Get the discover info associated with a ver attribute.
+ *
+ * @param ver the ver attribute.
+ * @return the discover info or null if it was not cached.
+ */
public DiscoverInfo getDiscoverInfo(String ver) {
return mVerCache.get(ver);
}
+ /**
+ * Get the discover info of a contact.
+ *
+ * @param jid the jid of the contact.
+ * @param ver the ver attribute of the contact capability.
+ * @return The info of the client null if the info was not cached.
+ */
public DiscoverInfo getDiscoverInfo(String jid, String ver) {
DiscoverInfo info = mVerCache.get(ver);
if (info == null)
@@ -62,13 +152,23 @@
return info;
}
- /**
- *
- *
- * @param jid
- * @param ver
- * @param hashMethod
- * @return
+ /**
+ * Set the node attribute to send in your capability.
+ * This is usually an uri to identify the client.
+ *
+ * @param node the node attribute to set.
+ */
+ public void setNode(String node) {
+ mNode = node;
+ }
+
+ /**
+ * Validate the ver attribute of a received capability.
+ *
+ * @param jid the jid of the sender of the capability.
+ * @param ver the ver attribute of the capability.
+ * @param hashMethod the hash algorithm to use to calculate ver
+ * @return true if the ver attribute is valid false otherwise.
*/
private boolean validate(String jid, String ver, String hashMethod) {
try {
@@ -84,43 +184,56 @@
return res;
} catch (XMPPException e) {
e.printStackTrace();
- return false;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
- return false;
}
+ return false;
}
+ /**
+ * Calculate the ver attribute.
+ *
+ * @param info The discover info to calculate the ver.
+ * @param hashMethod the hash algorithm to use.
+ * @return the value of the ver attribute
+ * @throws NoSuchAlgorithmException if the hash algorithm is not supported.
+ */
private String calculateVer(DiscoverInfo info, String hashMethod) throws NoSuchAlgorithmException {
- StringBuilder S = new StringBuilder();
- for(DiscoverInfo.Identity identity : getSortedIdentity(info)) {
+ StringBuilder s = new StringBuilder();
+ for (DiscoverInfo.Identity identity : getSortedIdentity(info)) {
String c = identity.getCategory();
if (c != null)
- S.append(c);
- S.append('/');
+ s.append(c);
+ s.append('/');
c = identity.getType();
if (c != null)
- S.append(c);
- S.append('/');
+ s.append(c);
+ s.append('/');
// Should add lang but it is not available
// c = identity.getType();
// if (c != null)
// S.append(c);
- S.append('/');
+ s.append('/');
c = identity.getName();
if (c != null)
- S.append(c);
- S.append('<');
+ s.append(c);
+ s.append('<');
}
for (String f : getSortedFeature(info)) {
- S.append(f);
- S.append('<');
+ s.append(f);
+ s.append('<');
}
// Should add data form (XEP 0128) but it is not available
- byte[] hash = getHash(hashMethod, S.toString().getBytes());
+ byte[] hash = getHash(hashMethod, s.toString().getBytes());
return StringUtils.encodeBase64(hash);
}
+ /**
+ * Get the identities sorted correctly to calculate the ver attribute.
+ *
+ * @param info the DiscoverInfo containing the identities
+ * @return the sorted list of identities.
+ */
private List<DiscoverInfo.Identity> getSortedIdentity(DiscoverInfo info) {
List<DiscoverInfo.Identity> result = new ArrayList<DiscoverInfo.Identity>();
Iterator<DiscoverInfo.Identity> it = info.getIdentities();
@@ -152,6 +265,12 @@
return result;
}
+ /**
+ * Get the features sorted correctly to calculate the ver attribute.
+ *
+ * @param info the DiscoverInfo containing the features
+ * @return the sorted list of features.
+ */
private List<String> getSortedFeature(DiscoverInfo info) {
List<String> result = new ArrayList<String>();
Iterator<DiscoverInfo.Feature> it = info.getFeatures();
@@ -163,18 +282,47 @@
return result;
}
- private byte[] getHash(String algo, byte[] data) throws NoSuchAlgorithmException {
- MessageDigest md = MessageDigest.getInstance(algo);
- return md.digest(data);
+ /**
+ * Get the Discover Information send by your own connection.
+ *
+ * @return your own DiscoverInfo
+ */
+ private DiscoverInfo getOwnInformation() {
+ DiscoverInfo result = new DiscoverInfo();
+ DiscoverInfo.Identity id = new DiscoverInfo.Identity("client", ServiceDiscoveryManager.getIdentityName());
+ id.setType(ServiceDiscoveryManager.getIdentityType());
+ result.addIdentity(id);
+ Iterator<String> it = mSdm.getFeatures();
+ while (it.hasNext()) {
+ result.addFeature(it.next());
+ }
+ return result;
}
+ /**
+ * Calculate a Hash (digest).
+ *
+ * @param algo the algorithm to use
+ * @param data the data to compute
+ * @return the resulting hash
+ * @throws NoSuchAlgorithmException if the algorithm is not supported
+ */
+ private byte[] getHash(String algo, byte[] data) throws NoSuchAlgorithmException {
+ MessageDigest md = MessageDigest.getInstance(algo);
+ return md.digest(data);
+ }
+
+ /**
+ * Initialize a list of supported Hash algorithm.
+ */
private void initSupportedAlgorithm() {
- String algo[] = new String[] {"md2", "md5", "sha-1", "sha-224", "sha-256", "sha-384", "sha-512" };
+ // sort by ""preference"
+ String[] algo = new String[] {"sha-1", "md2", "md5", "sha-224", "sha-256", "sha-384", "sha-512" };
for (String a : algo) {
try {
MessageDigest md = MessageDigest.getInstance(a);
mSupportedAlgorithm.add(a);
- } catch(NoSuchAlgorithmException e) {
+ } catch (NoSuchAlgorithmException e) {
System.err.println("Hash algorithm " + a + " not supported");
}
}
--- a/src/com/beem/project/beem/smack/caps/CapsProvider.java Thu Jul 22 23:34:36 2010 +0200
+++ b/src/com/beem/project/beem/smack/caps/CapsProvider.java Mon Jul 26 01:21:28 2010 +0200
@@ -1,12 +1,65 @@
+/*
+ BEEM is a videoconference application on the Android Platform.
+ Copyright (C) 2009 by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ This file is part of BEEM.
+
+ BEEM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ BEEM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BEEM. If not, see <http://www.gnu.org/licenses/>.
+
+ Please send bug reports with examples or suggestions to
+ contact@beem-project.com or http://dev.beem-project.com/
+
+ Epitech, hereby disclaims all copyright interest in the program "Beem"
+ written by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ Nicolas Sadirac, November 26, 2009
+ President of Epitech.
+
+ Flavien Astraud, November 26, 2009
+ Head of the EIP Laboratory.
+
+*/
package com.beem.project.beem.smack.caps;
import org.xmlpull.v1.XmlPullParser;
import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smack.packet.PacketExtension;
+/**
+ * PacketExtensionProvider for XEP-0115.
+ * This provider parse c element of namespace
+ * http://jabber.org/protocol/caps which represents a capability of XEP-0115
+ *
+ */
public class CapsProvider implements PacketExtensionProvider {
+ /**
+ * Constructor.
+ */
+ public CapsProvider() { }
+
@Override
public PacketExtension parseExtension(XmlPullParser parser) {
String ver = parser.getAttributeValue("", "ver");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/smack/caps/package-info.java Mon Jul 26 01:21:28 2010 +0200
@@ -0,0 +1,48 @@
+/*
+ BEEM is a videoconference application on the Android Platform.
+
+ Copyright (C) 2009 by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ This file is part of BEEM.
+
+ BEEM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ BEEM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with BEEM. If not, see <http://www.gnu.org/licenses/>.
+
+ Please send bug reports with examples or suggestions to
+ contact@beem-project.com or http://dev.beem-project.com/
+
+ Epitech, hereby disclaims all copyright interest in the program "Beem"
+ written by Frederic-Charles Barthelery,
+ Jean-Manuel Da Silva,
+ Nikita Kozlov,
+ Philippe Lago,
+ Jean Baptiste Vergely,
+ Vincent Veronis.
+
+ Nicolas Sadirac, November 26, 2009
+ President of Epitech.
+
+ Flavien Astraud, November 26, 2009
+ Head of the EIP Laboratory.
+
+*/
+
+/**
+ * This package contains implementation of XEP-0115.
+ */
+package com.beem.project.beem.smack.caps;