# HG changeset patch # User Da Risk # Date 1280100088 -7200 # Node ID 5dd9d68b6ad3e5fd792f37aa3ac759ecd50d9911 # Parent 4fb9df09ffdf88ff56be6a7b4cf1bf04056b4592 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. diff -r 4fb9df09ffdf -r 5dd9d68b6ad3 src/com/beem/project/beem/service/XmppConnectionAdapter.java --- 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"); } /** diff -r 4fb9df09ffdf -r 5dd9d68b6ad3 src/com/beem/project/beem/smack/caps/CapsExtension.java --- 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 . + + 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(); + } + } diff -r 4fb9df09ffdf -r 5dd9d68b6ad3 src/com/beem/project/beem/smack/caps/CapsManager.java --- 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 . + + 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 mVerCache = new ReferenceMap(); - Map mJidCache = new ReferenceMap(); + private Map mVerCache = new ReferenceMap(); + private Map mJidCache = new ReferenceMap(); private ServiceDiscoveryManager mSdm; private Connection mConnection; + private String mNode; private List mSupportedAlgorithm = new ArrayList(); - 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 getSortedIdentity(DiscoverInfo info) { List result = new ArrayList(); Iterator 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 getSortedFeature(DiscoverInfo info) { List result = new ArrayList(); Iterator 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 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"); } } diff -r 4fb9df09ffdf -r 5dd9d68b6ad3 src/com/beem/project/beem/smack/caps/CapsProvider.java --- 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 . + + 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"); diff -r 4fb9df09ffdf -r 5dd9d68b6ad3 src/com/beem/project/beem/smack/caps/package-info.java --- /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 . + + 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;