Merge
authorDa Risk <darisk972@gmail.com>
Tue, 10 Aug 2010 20:36:16 +0200
changeset 796 e85bccf2d817
parent 795 b2572c048dd7 (diff)
parent 792 310796265f15 (current diff)
child 797 fbd3585af53e
child 799 b2a796654230
Merge
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/asmack-beem/beem_patches/50-public-info-features.patch	Tue Aug 10 20:36:16 2010 +0200
@@ -0,0 +1,18 @@
+--- org/jivesoftware/smackx/packet/DiscoverInfo.java	2010-07-22 22:16:27.000000000 +0200
++++ org/jivesoftware/smackx/packet/DiscoverInfo.java	2010-07-22 22:58:43.000000000 +0200
+@@ -62,7 +62,7 @@
+      *
+      * @return an Iterator on the discovered features of an XMPP entity
+      */
+-    Iterator<Feature> getFeatures() {
++    public Iterator<Feature> getFeatures() {
+         synchronized (features) {
+             return Collections.unmodifiableList(features).iterator();
+         }
+@@ -266,4 +266,4 @@
+             return buf.toString();
+         }
+     }
+-}
+\ Pas de fin de ligne à la fin du fichier.
++}
Binary file libs/asmack-android-7-beem.jar has changed
--- a/src/com/beem/project/beem/BeemService.java	Fri Jul 23 14:19:41 2010 +0200
+++ b/src/com/beem/project/beem/BeemService.java	Tue Aug 10 20:36:16 2010 +0200
@@ -51,6 +51,8 @@
 import org.jivesoftware.smack.provider.PrivacyProvider;
 import org.jivesoftware.smack.provider.ProviderManager;
 import org.jivesoftware.smackx.provider.DelayInfoProvider;
+import org.jivesoftware.smackx.provider.DiscoverInfoProvider;
+import org.jivesoftware.smackx.provider.DiscoverItemsProvider;
 import org.jivesoftware.smackx.packet.ChatStateExtension;
 import org.jivesoftware.smack.proxy.ProxyInfo;
 import org.jivesoftware.smack.proxy.ProxyInfo.ProxyType;
@@ -78,6 +80,7 @@
 import com.beem.project.beem.utils.BeemBroadcastReceiver;
 import com.beem.project.beem.utils.BeemConnectivity;
 import com.beem.project.beem.utils.Status;
+import com.beem.project.beem.smack.caps.CapsProvider;
 
 /**
  * This class is for the Beem service.
@@ -319,6 +322,11 @@
 	// Delayed Delivery only the new version
 	pm.addExtensionProvider("delay", "urn:xmpp:delay", new DelayInfoProvider());
 
+	// Service Discovery # Items
+	pm.addIQProvider("query", "http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
+	// Service Discovery # Info
+	pm.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
+
 	// Chat State
 	ChatStateExtension.Provider chatState = new ChatStateExtension.Provider();
 	pm.addExtensionProvider("active", "http://jabber.org/protocol/chatstates", chatState);
@@ -327,6 +335,7 @@
 	pm.addExtensionProvider("paused", "http://jabber.org/protocol/chatstates", chatState);
 	pm.addExtensionProvider("inactive", "http://jabber.org/protocol/chatstates", chatState);
 	pm.addExtensionProvider("gone", "http://jabber.org/protocol/chatstates", chatState);
+	pm.addExtensionProvider("c", "http://jabber.org/protocol/caps", new CapsProvider());
 	/*
 	// Private Data Storage
 	pm.addIQProvider("query", "jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider());
@@ -344,10 +353,6 @@
 	pm.addExtensionProvider("html", "http://jabber.org/protocol/xhtml-im", new XHTMLExtensionProvider());
 	// Group Chat Invitations
 	pm.addExtensionProvider("x", "jabber:x:conference", new GroupChatInvitation.Provider());
-	// Service Discovery # Items
-	pm.addIQProvider("query", "http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
-	// Service Discovery # Info
-	pm.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
 	// Data Forms
 	pm.addExtensionProvider("x", "jabber:x:data", new DataFormProvider());
 	// MUC User
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/service/BeemCapsManager.java	Tue Aug 10 20:36:16 2010 +0200
@@ -0,0 +1,162 @@
+/*
+    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.service;
+
+import org.jivesoftware.smack.Connection;
+import org.jivesoftware.smackx.packet.DiscoverInfo;
+import org.jivesoftware.smackx.ServiceDiscoveryManager;
+import org.jivesoftware.smack.util.PacketParserUtils;
+import org.xmlpull.v1.XmlPullParserFactory;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParser;
+
+import android.util.Log;
+import java.io.FileReader;
+import java.io.Reader;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.Writer;
+
+import java.io.File;
+import java.io.IOException;
+
+import android.content.Context;
+
+import com.beem.project.beem.smack.caps.CapsManager;
+
+/**
+ * An implementation of CapsManager which keeps DiscoverInfo on the Cache directory of the android application.
+ */
+public class BeemCapsManager extends CapsManager {
+
+    private static final String TAG = "BeemCapsManager";
+
+    private Context mContext;
+    private File mCacheDir;
+    private XmlPullParser mParser;
+
+    /**
+     * Create a BeemCapsManager.
+     *
+     * @param sdm the ServiceDiscoveryManager to use
+     * @param conn the connection to use
+     * @param context the Android context to use to store data
+     */
+    public BeemCapsManager(final ServiceDiscoveryManager sdm, final Connection conn, final Context context) {
+	super(sdm, conn);
+	mContext = context;
+	initCacheDirectory();
+    }
+
+
+    @Override
+    protected DiscoverInfo load(String ver) {
+	File fver = new File(mCacheDir, ver);
+	try {
+	    Reader fr = new BufferedReader(new FileReader(fver));
+	    try {
+		if (mParser == null)
+		    mParser = makeParser();
+		mParser.setInput(fr);
+		return (DiscoverInfo) PacketParserUtils.parsePacketExtension("query",
+			"http://jabber.org/protocol/disco#info", mParser);
+
+	    } finally {
+		fr.close();
+	    }
+	} catch (Exception e) {
+	    // The parsePacketExtension throw Exception on error
+	    Log.d(TAG, "Error while loading Capabilities " + ver, e);
+	}
+	return null;
+    }
+
+    @Override
+    protected void store(String ver, DiscoverInfo info) {
+	File fver = new File(mCacheDir, ver);
+	try {
+	    Writer fw = new BufferedWriter(new FileWriter(fver));
+	    try {
+		String data  = info.toXML();
+		fw.write(data, 0, data.length());
+	    } finally {
+		fw.close();
+	    }
+	} catch (IOException e) {
+	    Log.d(TAG, "Error while saving Capabilities " + ver, e);
+	}
+    }
+
+    @Override
+    protected boolean isInCache(String ver) {
+	boolean result = super.isInCache(ver);
+	if (!result) {
+	    File fver = new File(mCacheDir, ver);
+	    result = fver.exists();
+	}
+	return result;
+    }
+
+    /**
+     * Init the cache directory.
+     */
+    private void initCacheDirectory() {
+	File dir = mContext.getCacheDir();
+	mCacheDir = new File(dir, "capabilities");
+	mCacheDir.mkdir();
+    }
+
+    /**
+     * Make an Xml parser.
+     *
+     * @return the created xml parser.
+     * @throws XmlPullParserException if an error occurs while creating the parser.
+     */
+    private XmlPullParser makeParser() throws XmlPullParserException {
+	XmlPullParserFactory fact = XmlPullParserFactory.newInstance();
+	fact.setNamespaceAware(true);
+	return fact.newPullParser();
+    }
+}
--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Fri Jul 23 14:19:41 2010 +0200
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Tue Aug 10 20:36:16 2010 +0200
@@ -205,9 +205,6 @@
 	if (!mAdaptee.isConnected())
 	    return false;
 	try {
-	    mAdaptee.login(mLogin, mPassword, mResource);
-	    mChatManager = new BeemChatManager(mAdaptee.getChatManager(), mService);
-	    mPrivacyListManager = new PrivacyListManagerAdapter(PrivacyListManager.getInstanceFor(mAdaptee));
 
 	    this.initFeatures(); // pour declarer les features xmpp qu'on
 	    // supporte
@@ -227,6 +224,9 @@
 
 	    mAdaptee.addPacketListener(mSubscribePacketListener, filter);
 
+	    mAdaptee.login(mLogin, mPassword, mResource);
+	    mChatManager = new BeemChatManager(mAdaptee.getChatManager(), mService);
+	    mPrivacyListManager = new PrivacyListManagerAdapter(PrivacyListManager.getInstanceFor(mAdaptee));
 	    mService.resetStatus();
 	    mService.initJingle(mAdaptee);
 
@@ -387,12 +387,17 @@
      * 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);
 	sdm.addFeature("http://jabber.org/protocol/disco#info");
 	sdm.addFeature("jabber:iq:privacy");
+	sdm.addFeature("http://jabber.org/protocol/caps");
 	mChatStateManager = ChatStateManager.getInstance(mAdaptee);
+	BeemCapsManager caps = new BeemCapsManager(sdm, mAdaptee, mService);
+	caps.setNode("http://www.beem-project.com");
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/smack/caps/CapsExtension.java	Tue Aug 10 20:36:16 2010 +0200
@@ -0,0 +1,174 @@
+/*
+    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.
+ *
+ */
+public class CapsExtension implements PacketExtension {
+
+    private String mVer;
+    private String mHash;
+    private String mNode;
+    private String mExt;
+
+
+    /**
+     * 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;
+    }
+
+    /**
+     * Get the ver attribute value.
+     *
+     * @return the value of the ver attribute.
+     */
+    public String getVer() {
+	return mVer;
+    }
+
+    /**
+     * Get the hash attribute value.
+     *
+     * @return the value of the hash attribute.
+     */
+    public String getHash() {
+	return mHash;
+    }
+
+    /**
+     * Get the node attribute value.
+     *
+     * @return the value of the node attribute.
+     */
+    public String getNode() {
+	return mNode;
+    }
+
+    /**
+     * 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() {
+	return "c";
+    }
+
+    @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();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/smack/caps/CapsManager.java	Tue Aug 10 20:36:16 2010 +0200
@@ -0,0 +1,371 @@
+/*
+    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;
+import java.util.Iterator;
+import java.util.Comparator;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.security.NoSuchAlgorithmException;
+import java.security.MessageDigest;
+
+import org.jivesoftware.smack.util.StringUtils;
+
+/**
+ * Capabilities manager to implements XEP-0115.
+ * The DiscoverInfo are cached in memory.
+ *
+ */
+public class CapsManager {
+    // the verCache should be stored on disk
+    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>();
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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) {
+	    info = load(ver);
+	    if (info == null)
+		info = mJidCache.get(jid);
+	}
+	return info;
+    }
+
+    /**
+     * 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;
+    }
+
+    /**
+     * Load a persistent DiscoverInfo.
+     * The default implementation does nothing and always return null.
+     *
+     * @param ver the ver hash of the discoverInfo.
+     * @return The discover info or null if not present.
+     */
+    protected DiscoverInfo load(String ver) {
+	return null;
+    }
+
+    /**
+     * Store a DiscoverInfo for persistence.
+     * The default implementation does nothing.
+     *
+     * @param ver the ver hash of the DiscoverInfo
+     * @param info the DiscoverInfo to store
+     */
+    protected void store(String ver, DiscoverInfo info) {
+    }
+
+    /**
+     * Check if the discover info correspondig to the ver hash is in cache.
+     * This implementation checks the memory cache.
+     * If the info is not in cache it is necessary to request it from the network.
+     *
+     * @param ver the ver hash
+     * @return true if it is in cache false otherwise
+     */
+    protected boolean isInCache(String ver) {
+	return mVerCache.containsKey(ver);
+    }
+
+    /**
+     * Initialize this CapsManageer.
+     */
+    private void init() {
+	initSupportedAlgorithm();
+	PacketFilter filter = new PacketExtensionFilter("c", "http://jabber.org/protocol/caps");
+	mConnection.addPacketListener(new PacketListener() {
+	    public void processPacket(Packet packet) {
+		if (packet.getFrom().equals(mConnection.getUser()))
+		    return;
+		PacketExtension p = packet.getExtension("c", "http://jabber.org/protocol/caps");
+		CapsExtension caps = (CapsExtension) p;
+		if (!isInCache(caps.getVer())) {
+		    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));
+    }
+
+    /**
+     * 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 {
+	    DiscoverInfo info = mSdm.discoverInfo(jid);
+	    if (!mSupportedAlgorithm.contains(hashMethod)) {
+		mJidCache.put(jid, info);
+		return false;
+	    }
+	    String v = calculateVer(info, hashMethod);
+	    boolean res = v.equals(ver);
+	    if (res) {
+		mVerCache.put(ver, info);
+		store(ver, info);
+	    }
+	    return res;
+	} catch (XMPPException e) {
+	    e.printStackTrace();
+	} catch (NoSuchAlgorithmException e) {
+	    e.printStackTrace();
+	}
+	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)) {
+	    String c = identity.getCategory();
+	    if (c != null)
+		s.append(c);
+	    s.append('/');
+	    c = identity.getType();
+	    if (c != null)
+		s.append(c);
+	    s.append('/');
+	    // Should add lang but it is not available
+//             c = identity.getType();
+//             if (c != null)
+//                 S.append(c);
+	    s.append('/');
+	    c = identity.getName();
+	    if (c != null)
+		s.append(c);
+	    s.append('<');
+	}
+	for (String f : getSortedFeature(info)) {
+	    s.append(f);
+	    s.append('<');
+	}
+	// Should add data form (XEP 0128) but it is not available
+	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();
+	while (it.hasNext()) {
+	    DiscoverInfo.Identity id = it.next();
+	    result.add(id);
+	}
+	Collections.sort(result, new Comparator<DiscoverInfo.Identity>() {
+	    public int compare(DiscoverInfo.Identity o1, DiscoverInfo.Identity o2) {
+
+		String cat1 = o1.getCategory();
+		if (cat1 == null) cat1 = "";
+		String cat2 = o2.getCategory();
+		if (cat2 == null) cat2 = "";
+		int res = cat1.compareTo(cat2);
+		if (res != 0)
+		    return res;
+		String type1 = o1.getType();
+		if (type1 == null) type1 = "";
+		String type2 = o2.getCategory();
+		if (type2 == null) type2 = "";
+		res = type1.compareTo(type2);
+		if (res != 0)
+		    return res;
+		// should compare lang but not avalaible
+		return 0;
+	    }
+	});
+	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();
+	while (it.hasNext()) {
+	    DiscoverInfo.Feature feat = it.next();
+	    result.add(feat.getVar());
+	}
+	Collections.sort(result);
+	return result;
+    }
+
+    /**
+     * 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() {
+	// 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) {
+		System.err.println("Hash algorithm " + a + " not supported");
+	    }
+	}
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/smack/caps/CapsProvider.java	Tue Aug 10 20:36:16 2010 +0200
@@ -0,0 +1,74 @@
+/*
+    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");
+	String hash = parser.getAttributeValue("", "hash");
+	String node = parser.getAttributeValue("", "node");
+	String ext = parser.getAttributeValue("", "ext");
+	CapsExtension e = new CapsExtension(hash, node, ver);
+	e.setExt(ext);
+	return e;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/smack/caps/package-info.java	Tue Aug 10 20:36:16 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;