How to connect to Facebook Chat using X-FACEBOOK-PLATFORM mechanism

Hello, I’m just an amateur with smack api, and I’m trying hard to connect to facebook chat using x-facebook platform. I have gone through several blog posts and forums for getting it done. Facebook offers very unconcise documentation for this.

I have found a custom SASL mechanism class for facebook authentication. But getting errors, actually I do not know exactly how to perform this.

public class SASLXFacebookPlatformMechanism extends SASLMechanism {
    public static final String NAME = "X-FACEBOOK-PLATFORM";     private String apiKey = "";
    private String applicationSecret = "";
    private String sessionKey = "";     /**
     * Constructor.
     */
    public SASLXFacebookPlatformMechanism1(SASLAuthentication saslAuthentication) {
        super(saslAuthentication);
    }     @Override
    protected void authenticate() throws IOException, XMPPException {
        StringBuilder stanza = new StringBuilder();
        stanza.append("<auth mechanism=\"").append(getName());
        stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
        stanza.append("</auth>");         // Send the authentication to the server
        getSASLAuthentication().send(stanza.toString());
    }     @Override
    public void authenticate(String apiKeyAndSessionKey, String host, String applicationSecret) throws IOException, XMPPException {
        if (apiKeyAndSessionKey == null || applicationSecret == null)
            throw new IllegalArgumentException("Invalid parameters");         String[] keyArray = apiKeyAndSessionKey.split("\\|", 2);
        if (keyArray.length < 2)
            throw new IllegalArgumentException("API key or session key is not present");         this.apiKey = keyArray[0];
        this.applicationSecret = applicationSecret;
        this.sessionKey = keyArray[1];         this.authenticationId = sessionKey;
        this.password = applicationSecret;
        this.hostname = host;         String[] mechanisms = { "DIGEST-MD5" };
        Map<String, String> props = new HashMap<String, String>();
        this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this);
        authenticate();
    }     @Override
    public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
        String[] mechanisms = { "DIGEST-MD5" };
        Map<String, String> props = new HashMap<String, String>();
        this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, cbh);
        authenticate();
    }     @Override
    protected String getName() {
        return NAME;
    }     @Override
    public void challengeReceived(String challenge) throws IOException {
        StringBuilder stanza = new StringBuilder();
        byte[] response = null;         if (challenge != null) {
            String decodedChallenge = new String(Base64.decode(challenge));
            Map<String, String> parameters = getQueryMap(decodedChallenge);             String version = "1.0";
            String nonce = parameters.get("nonce");
            String method = parameters.get("method");             long callId = new GregorianCalendar().getTimeInMillis() / 1000L;             String sig = "api_key=" + apiKey
                            + "call_id=" + callId
                            + "method=" + method
                            + "nonce=" + nonce
                            + "session_key=" + sessionKey
                            + "v=" + version
                            + applicationSecret;             try {
                sig = md5(sig);
            }
            catch (NoSuchAlgorithmException e) {
                throw new IllegalStateException(e);
            }             String composedResponse = "api_key=" + URLEncoder.encode(apiKey, "utf-8")
                                        + "&call_id=" + callId
                                        + "&method=" + URLEncoder.encode(method, "utf-8")
                                        + "&nonce=" + URLEncoder.encode(nonce, "utf-8")
                                        + "&session_key=" + URLEncoder.encode(sessionKey, "utf-8")
                                        + "&v=" + URLEncoder.encode(version, "utf-8")
                                        + "&sig=" + URLEncoder.encode(sig, "utf-8");             response = composedResponse.getBytes("utf-8");
        }         String authenticationText = "";         if (response != null)
            authenticationText = Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);         stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
        stanza.append(authenticationText);
        stanza.append("</response>");         // Send the authentication to the server
        getSASLAuthentication().send(stanza.toString());
    }     private Map<String, String> getQueryMap(String query) {
        Map<String, String> map = new HashMap<String, String>();
        String[] params = query.split("\\&");         for (String param : params) {
            String[] fields = param.split("=", 2);
            map.put(fields[0], (fields.length > 1 ? fields[1] : null));
        }         return map;
    }     private String md5(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(text.getBytes("utf-8"), 0, text.length());
        return convertToHex(md.digest());
    }     private String convertToHex(byte[] data) {
        StringBuilder buf = new StringBuilder();
        int len = data.length;         for (int i = 0; i < len; i++) {
            int halfByte = (data[i] >>> 4) & 0xF;
            int twoHalfs = 0;             do {
                if (0 <= halfByte && halfByte <= 9)
                    buf.append((char) ('0' + halfByte));
                else
                    buf.append((char) ('a' + halfByte - 10));
                halfByte = data[i] & 0xF;
            }
            while (twoHalfs++ < 1);
        }         return buf.toString();
    }
}

So now I have this class, but I don’t know where I am doing wrong, may be I’m calling it in wrong manner, here is how I made use of this class.

ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
config.setSASLAuthenticationEnabled(true);
config.setDebuggerEnabled(true); SASLAuthentication.registerSASLMechanism(SASLXFacebookPlatformMechanism.NAME, SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism(SASLXFacebookPlatformMechanism1.NAME, 0); XMPPConnection connection = new XMPPConnection(config);
try {
    connection.connect();
} catch (XMPPException ex) {
    Logger.getLogger(FB.class.getName()).log(Level.SEVERE, null, ex);
}
SASLXFacebookPlatformMechanism1 mech=new SASLXFacebookPlatformMechanism1(connection.getSASLAuthentication());
try {
    mech.authenticate();
} catch (IOException ex) {
    Logger.getLogger(FB.class.getName()).log(Level.SEVERE, null, ex);
} catch (XMPPException ex) {
    Logger.getLogger(FB.class.getName()).log(Level.SEVERE, null, ex);
}

When I execute this code, I get a NullPointerException

java.lang.NullPointerException
    at org.jivesoftware.smack.SASLAuthentication.challengeReceived(SASLAuthentication.java:514)
    at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:296)
    at org.jivesoftware.smack.PacketReader.access$000(PacketReader.java:43)
    at org.jivesoftware.smack.PacketReader$1.run(PacketReader.java:70)