Package

Source Code of NetworkThread

import java.io.DataInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.Vector;

import javax.microedition.io.Connection;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.io.HttpsConnection;
import javax.microedition.io.SocketConnection;

import com.twmacinta.util.MD5;


/**
* @author Vorobev
*
* Main class for network packets processing
*
*/
public class NetworkThread extends Thread{
   
    private boolean ended = false; //Network error flag
   
    private boolean busy = false; //Indicates if someone reads packet
   
    private boolean google = false; //Google Talk server flag
   
    private boolean terminated = false; //Indicates if someone closed connection
   
    private boolean statusSet = false; //Indicates that status text from profile already has been set
   
    private String token = ""; //Google token holder
   
    private boolean inCycle = false;
   
   
    /**
     * Converts String to UTF-8 String. Code from Colibry IM messenger used
     * @param s String to convert
     * @return converted String
     */
    public static String ToUTF(String s) {
        int i = 0;
        StringBuffer stringbuffer = new StringBuffer();
       
        for (int j = s.length(); i < j; i++) {
            int c = (int) s.charAt(i);
            if ((c >= 1) && (c <= 0x7f)) {
                stringbuffer.append((char) c);
            }
            if (((c >= 0x80) && (c <= 0x7ff)) || (c == 0)) {
                stringbuffer.append((char) (0xc0 | (0x1f & (c >> 6))));
                stringbuffer.append((char) (0x80 | (0x3f & c)));
            }
            if ((c >= 0x800) && (c <= 0xffff)) {
                stringbuffer.append(((char) (0xe0 | (0x0f & (c >> 12)))));
                stringbuffer.append((char) (0x80 | (0x3f & (c >> 6))));
                stringbuffer.append(((char) (0x80 | (0x3f & c))));
            }
        }
       
        return stringbuffer.toString();
    }
   
    private void reconnect() {
        ended = true;
        if(log.getProfile().getAutoReconnect()>0)
            log.newSession(log.getDisplay(), log.getProfile());
    }
   
        /*
         * Terminates current NetworkThread softly
         * Closes connection, informs user about it, and sets ended flag
         * */
    public synchronized void terminate() {
        terminate(true);
    }
   
    public synchronized void terminate(boolean play) {
        if(terminated)
            return;
        try {
            log.addMessage("Disconnected");
        } catch (Exception e2) {
        }
        ended = true;
        terminated = true;
        try {
            conn.close();
            is.close();
            os.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
//      e.printStackTrace();
            System.out.println("Ex1");
        }
        try {
            log.setCurrent();
        } catch (Exception e1) {
            // TODO Auto-generated catch block
//      e1.printStackTrace();
            System.out.println("Ex2");
        }
        notify();
        System.out.println("Ended set to true");
        try {
            Thread.sleep(510);
            if(play)
                reconnect();
        } catch (Exception e) {
//      e.printStackTrace();
            System.out.println("Ex3");
        }
    }
   
//  private RosterList list = null;
    private ConnectLog log;
    /**
     * Constructs thread and starts it
     * @param l
     */
    public NetworkThread(ConnectLog l) {
        log = l;
        start();
    }
   
   
        /* (non-Javadoc)
         * @see java.lang.Runnable#run()
         *
         * Main method that processes jabber packets
         */
    public void run() {
        log.addMessage("Connecting...");
                /*
                 * Username must consists of 3 parts: <user>@<domain>
                 * Split username and extract user and domain values
                 * */
        String user = log.getProfile().getUser();
        if(user.indexOf("@")==-1) {
            log.addMessage("Invalid username "+user);
            reconnect();
            return;
        }
        String domain = user.substring(user.indexOf("@")+1, user.length());
        user = user.substring(0, user.indexOf("@"));
                /*
                 * Constructs Jabber server address
                 * */
        String addr = log.getProfile().getHost()+":"+log.getProfile().getPort();
        if(log.getProfile().getSsl()==1)
            addr = "ssl://"+addr;
        else
            addr = "socket://"+addr;
                /*
                 * If user wants to work with Google server - generate it
                 * */
        if(log.getProfile().getIsGoogle()>0){
            if(log.getProfile().getUseMyServer()>0)
                token = getGoogleTokenViaMyServer(log.getProfile().getUser(), log.getProfile().getPass());
            else
                token = getGoogleToken(log.getProfile().getUser(), log.getProfile().getPass());           
        }
        if(ended) {
            reconnect();
            return;
        }
        try {
                        /*
                         * Starts session with jabber server
                         * */
            startSession(addr, domain, user, log.getProfile().getPass(), "Mobile", log.getProfile().getStatus());
        }catch(Exception e) {
            //If any exception throws - terminate connection
            log.addMessage(e.getMessage());
            reconnect();
            return;
        }
        if(ended) {
            reconnect();
            return;
        }
        log.addMessage("Successfully connected with "+log.getProfile().getUser());
        String show = "";
        if(log.getProfile().getStatusID()==1)
            show = "away";
        if(log.getProfile().getStatusID()==2)
            show = "xa";
        if(log.getProfile().getStatusID()==3)
            show = "dnd";
        //Calculates string representation of initial user status
        if(isGoogle()) {
            //Sets important Google settings
            if(ended) {
                reconnect();
                return;
            }
            System.out.println("isGoogle");
            writeToAir("<iq type=\"get\" id=\"6\"><query xmlns=\"google:relay\"/></iq>");
            //Informs Google Talk that we want to use GTalk features
            XmlNode y = readStanza();
            if(y.getAttr("type").equals("error")) {
                //Sorry :(
                ended = true;
            } else {
                writeToAir("<iq type=\"set\" to=\""+log.getProfile().getUser()+"\" id=\"15\"><usersetting xmlns=\"google:setting\"><autoacceptrequests value=\"false\"/>"+
                        "<mailnotifications value=\"true\"/></usersetting></iq>");
                //Sends mail notification request to GTalk server
                y = readStanza();
                if(y.getAttr("type").equals("error")) {
                    //Sorry :(
                    ended = true;
                }
               
            }
        }
        if(!ended) {
            if(!isGoogle())
                writeToAir("<presence><show>"+show+"</show><status>"+log.getProfile().getStatus()+"</status></presence>");
            //Send current status and status text to non Google Talk servers
            writeToAir("<iq type=\"get\" id=\"roster\">" +
                    "<query xmlns=\"jabber:iq:roster\"/></iq>");
            //Requests roster items (for all servers)
            if(isGoogle()) {
                writeToAir("<presence><show></show><status></status></presence>");
                writeToAir("<iq type=\"get\" id=\"23\"><query xmlns=\"google:mail:notify\" q=\"(!label:^s) (!label:^k) ((label:^u) (label:^i) (!label:^vm))\"/></iq>" +
                        "<iq type=\"get\" to=\""+log.getProfile().getUser()+"\" id=\"21\"><query xmlns=\"google:shared-status\"/></iq>");
                                /*
                                 * 1. Sets empty status and status text for GTalk server -
                                 *     GTalk will return last/current status and status text
                                 * 2. Requests new mail count and mail info
                                 * 3. Requests google shared status lists
                                 * */
            }
        }
        long nowTime = new Date().getTime();
        inCycle = true;
        log.initRoster();
        log.getRoster().getRoster().setTitle(log.getProfile().getUser());
        while(!ended) {
            //Main cycle
            try {
                if((is.available()>0)&&(!busy)) {
                    //if nobody reads packet and data is ready - get packet
                    XmlNode x = readOneStanza();
                    if(x.getName().equals("")) {
                        //Data empty - continue sleep
                        continue;
                    }
                    {
                        if(x.getName().equals("iq")&&x.child("query").getAttr("xmlns").equals("jabber:iq:roster")) {
                            //Data about contact received. Processes all "query" childs and updates info abount contact
                            Vector v = x.child("query").getChilds();
                            log.getRoster().setFullJid(x.getAttr("to"));
                            for(int i=0; i<v.size() ;i++) {
                                XmlNode y = (XmlNode) v.elementAt(i);
                                //Show contacts only with "both" and "to" subscriptions
                                if(y.getAttr("subscription").equals("both"))
                                    log.getRoster().getRosterFactory().updateContact(y.getAttr("jid").toLowerCase(), y.getAttr("name"), null, null);
                            }
                        }
                       
                        if(x.getName().equals("presence")) {
                            //We are here if someone changes own status
                            log("Need to change presence");
                            if(x.getAttr("type").equals("subscribe")) {
                                //User requests authorization - Ask for decision from user
                                log.getRoster().playMessage();
                                new RequestAuth(log.getDisplay(),this, log.getDisplay().getCurrent(), x.getAttr("from"), log.getProfile().getUser());
                            }
                            //Updates contact info in a roster
                            log.getRoster().getRosterFactory().updateContact(x.getAttr("from").toLowerCase(), null, x.getAttr("type").equals("")?x.childValue("show"):x.getAttr("type"), x.childValue("status"));
                        }
                        if(x.getName().equals("message")&&!x.getAttr("type").equals("error")) {
                            //We received a Message, Lets RosterFactory process it!
                            log.getRoster().getRosterFactory().addMessage(x.getAttr("from").toLowerCase(), x.childValue("body"), x.getAttr("id"));
                            //            list.getDisplay().vibrate(1000);
                        }
                        if(x.getName().equals("iq")&&x.child("query").getAttr("xmlns").equals("jabber:iq:version")) {
                            //We received unsupported packet
                            System.out.println("Proceed");
                            writeToAir("<iq type=\"error\" to=\""+x.getAttr("from")+"\"><query xmlns=\"jabber:iq:version\"/><error code=\"501\" type=\"cancel\"><feature-not-implemented xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/></error></iq>");
                        }
                        if(x.getName().equals("iq") && isGoogle() && !x.child("mailbox").getAttr("result-time").equals("")) {
                            //New received mail response. Processes all mails and adds it to MailViewer
                            Vector v = x.child("mailbox").getChilds();
                            //Newer mails must be on top
                            for(int i=v.size()-1; i>=0; i--) {
                                XmlNode t = (XmlNode) v.elementAt(i);
                                if(i==0) {
                                    //Last mail. Remebers mail date and mail ID
                                    log.getRoster().setLastTime(t.getAttr("date"));
                                    log.getRoster().setTid(t.getAttr("tid"));
                                }
                                log.getRoster().getMails().addMail(t.child("senders").child("sender").getAttr("name"), t.childValue("subject"), t.childValue("snippet"));
                            }
                            if(v.size()>0) {
                                //Start MailViewer and play sound
                                log.getRoster().getMails().startMe();
                                log.getRoster().playMessage();
                            }
                        }
                        if(x.getName().equals("iq") && isGoogle() && x.child("new-mail").getAttr("xmlns").equals("google:mail:notify")) {
                                                        /*
                                                         * New mail notification. Requests new mails newer then remebered data and ID if this fields were stored before
                                                         */
                            writeToAir("<iq type=\"get\"><query xmlns=\"google:mail:notify\""+(log.getRoster().getLastTime().equals("")?"":" newer-than-time=\""+log.getRoster().getLastTime()+"\"")+(log.getRoster().getTid().equals("")?"":" newer-than-tid=\""+log.getRoster().getTid()+"\"")+" q=\"(!label:^s) (!label:^k) ((label:^u) (label:^i) (!label:^vm))\"/></iq>");
                        }
                        if(x.getName().equals("iq") && isGoogle() && x.child("query").getAttr("xmlns").equals("google:shared-status")) {
                            //We receive google:shared:list and current status ans status text
                            //If we dont want to set custom status - we store received status text
                            if(statusSet || log.getProfile().getLockStatusStr()==0)
                                log.getProfile().setStatus(x.child("query").childValue("status"));
                            //Next, we calculate new status ID
                            int newStatus = x.child("query").childValue("show").equals("")?0:
                                (x.child("query").childValue("show").equals("away")?1:3);
                            //Clears all status holders
                            log.getRoster().getOnlines().removeAllElements();
                            log.getRoster().getBusies().removeAllElements();
                            log.getRoster().getAways().removeAllElements();
                            Vector v = x.child("query").getChilds();
                            //This routine parses received packet and fills status holders
                            for(int i=0; i<v.size(); i++) {
                                XmlNode t = (XmlNode) v.elementAt(i);
                                if(t.getName().equals("status-list")) {
                                    Vector v2 = t.getChilds();
                                    for(int j=0; j<v2.size(); j++) {
                                        XmlNode t2 = (XmlNode) v2.elementAt(j);
                                        if(t.getAttr("show").equals("dnd"))
                                            log.getRoster().getBusies().addElement(t2.getValue());
                                        else
                                            if(t.getAttr("show").equals("away"))
                                                log.getRoster().getAways().addElement(t2.getValue());
                                            else
                                                log.getRoster().getOnlines().addElement(t2.getValue());
                                    }
                                }
                            }
                            if(log.getProfile().getStatusID()==2)
                                log.getProfile().setStatusID(1);
                            //Fix status ID for GTalk server (GTalk does not support XA status) I think so :)
                            //First if - we return our status back if lockStatus selected in profile by sending packet with old status
                            //Otherwise we store new status in profile
                            if(newStatus!=log.getProfile().getStatusID() &&
                                    log.getProfile().getLockStatus()>0)
                                generatePresense();
                            else
                                log.getProfile().setStatusID(newStatus);
                            //If we received status info first time and if we want to set custom status text - it's time to do this
                            if(!statusSet && log.getProfile().getLockStatusStr()>0) {
                                statusSet = true;
                                generatePresense();
                            }
                        }
                    }
                } else {
                    if(!busy) {
                        if(new Date().getTime()-nowTime>600000) {
                           
                            show = "";
                            if(log.getProfile().getStatusID()==1)
                                show = "away";
                            if(log.getProfile().getStatusID()==2)
                                show = "xa";
                            if(log.getProfile().getStatusID()==3)
                                show = "dnd";
                           
                            nowTime = new Date().getTime();
                            writeToAir("<presence from=\""+log.getRoster().getFullJid()+"\"><show>"+show+"</show><status>"+log.getProfile().getStatusStr()+"</status></presence>");
                        }
                    }
                    Thread.sleep(500);
                    //Wait for next packet
                }
            } catch (Exception e) {
                ended = true;
                //Sorry :)
            }
        }
        terminate();
    }
   
    private SocketConnection conn;
    private boolean isSecure = false;
    private InputStream is = null;
    private OutputStream os = null;
   
    /**
     * This routine reads next packet from stream. if we receive empty packet - we will try to do this later
     * @return
     */
    public XmlNode readStanza() {
        busy = true;
        XmlNode x = new XmlNode();
        if(ended) {
            terminate();
            return x;
        }
        do
        {
            if(!ended) {
                try {
                    x.init("", is);
                } catch (Exception e) {
                    ended = true;
                }
                busy = false;
            }
        }
        while(x.getName().equals("") && !ended);
        System.out.println(x);
       
        return x;
    }
   
    /**
     * This routine siply reads next packet from stream
     * @return
     */
    public XmlNode readOneStanza() {
        busy = true;
        XmlNode x = new XmlNode();
        if(ended) {
            terminate();
            return x;
        }
        if(!ended) {
            try {
                x.init("", is);
            } catch (Exception e) {
                ended = true;
            }
            busy = false;
        }
        System.out.println("RO:"+x);
        return x;
    }
   
   
    /**
     * Base16 encodes input string
     * @param s input string
     * @return output string
     */
    private String Base16Encode(String s) {
        String res = "";
        for(int i=0; i<s.length(); i++) {
            res += Integer.toHexString(s.charAt(i));
        }
        return res;
    }
   
    /**
     * This routine writes packet to stream
     * If Exception thrown, terminate is called
     * @param mess
     */
    public void writeToAir(String mess) {
        if(ended) {
            terminate();
            return;
        }
        try {
            if(os!=null) {
                os.write(ToUTF(mess).getBytes());
                os.flush();
            }
        } catch (Exception e) {
            ended = true;
        }
    }
   
    private Connection getConnection() {
        return conn;
    }
   
    /**
     * Establishes connection with Jabber server
     * @param addr
     * @throws Exception
     */
    private void initConnection(String addr) throws Exception {
        try {
            log.addMessage("Init connection to "+addr);
            conn = (SocketConnection) Connector.open(addr);
//      conn.setSocketOption(SocketConnection.LINGER, 0);
//      conn.setSocketOption(SocketConnection.SNDBUF, 30);
//      conn.setSocketOption(SocketConnection.RCVBUF, 30);
            conn.setSocketOption(SocketConnection.KEEPALIVE, 1);
            is  = conn.openInputStream();
            os = conn.openOutputStream();
            isSecure = false;
//      return true;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            throw new Exception(e.getMessage());
        }
//    return false;
    }
   
    /**
     * This routine generates MD5-DIGEST response via SASL specification
     * @param user
     * @param pass
     * @param realm
     * @param digest_uri
     * @param nonce
     * @param cnonce
     * @return
     */
    private String generateAuthResponse(String user, String pass, String realm, String digest_uri, String nonce, String cnonce) {
        String val1 = user+":"+realm+":"+pass;
        byte bb[] = new byte[17];
        bb = md5It(val1);
        int sl = new String(":"+nonce+":"+cnonce).length();
        byte cc[] = new String(":"+nonce+":"+cnonce).getBytes();
        byte bc[] = new byte[99];
        for(int i=0; i<16; i++) {
            bc[i] = bb[i];
        }
        for(int i=16; i<sl+16; i++) {
            bc[i] = cc[i-16];
        }
        String val2 = new String(MD5.toHex(md5It(bc, sl+16)));
        String val3 = "AUTHENTICATE:"+digest_uri;
        val3 = MD5.toHex(md5It(val3));
        String val4 = val2+":"+nonce+":00000001:"+cnonce+":auth:"+val3;
//    System.out.println("Before auth = "+val4+", val1 = "+val1);
        val4 = MD5.toHex(md5It(val4));
//    System.out.println("Val4 = "+val4);
       
        String enc = "charset=utf-8,username=\""+user+"\",realm=\""+realm+"\"," +
                "nonce=\""+nonce+"\",cnonce=\""+cnonce+"\"," +
                "nc=00000001,qop=auth,digest-uri=\""+digest_uri+"\"," +
                "response="+val4;
        String resp = MD5.toBase64(enc.getBytes());
        return resp;
    }
   
   
    /**
     * MD5 routines
     * @param s
     * @return
     */
    public byte[] md5It(String s) {
        byte bb[] = new byte[16];
        try {
            MD5 md2 = new MD5(s.getBytes());
            return md2.doFinal();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return bb;
    }
   
    public byte[] md5It(byte[] s, int l) {
        byte bb[] = new byte[16];
        try {
            byte tmp[] = new byte[l];
            for(int i=0; i<l;i++) {
                tmp[i] = s[i];
            }
            MD5 md2 = new MD5(tmp);
            return md2.doFinal();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return bb;
    }
   
    private void log(String s) {
//      System.out.println(s);
    }
   
   
    /**
     * Service routine
     * @param dis
     * @return
     */
    private String readLine(DataInputStream dis) {
        String s = "";
        byte ch = 0;
        try {
            while((ch = dis.readByte())!=-1) {
//        System.out.println("ch = "+ch);
                if(ch=='\n')
                    return s;
                s += (char)ch;
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return s;
    }
   
    /**
     * Generates X-GOOGLE-TOKEN response by communication with http://www.google.com
     * @param userName
     * @param passwd
     * @return
     */
    private String getGoogleToken(String userName, String passwd) {
        String first = "Email="+userName+"&Passwd="+passwd+"&PersistentCookie=false&source=googletalk";
        try {
            HttpsConnection c = (HttpsConnection) Connector.open("https://www.google.com:443/accounts/ClientAuth?"+first);
            log.addMessage("Connecting to www.google.com");
            DataInputStream dis = c.openDataInputStream();
            String str = readLine(dis);
            String SID = "";
            String LSID = "";
            if(str.startsWith("SID=")&&!ended) {
                SID = str.substring(4, str.length());
                str = readLine(dis);
                LSID = str.substring(5, str.length());
                first = "SID="+SID+"&LSID="+LSID+"&service=mail&Session=true";
                dis.close();
                c.close();
                c = (HttpsConnection) Connector.open("https://www.google.com:443/accounts/IssueAuthToken?"+first);
                log.addMessage("Next www.google.com connection");
                dis = c.openDataInputStream();
                str = readLine(dis);
                String token = MD5.toBase64(new String("\0"+userName+"\0"+str).getBytes());
                dis.close();
                c.close();
                return token;
            } else
                throw new Exception("Invalid response");
        }catch(Exception ex) {
            ex.printStackTrace();
            System.out.println("EX: "+ex.toString());
        }
        return "";
    }
   
   
    /**
     * Generates X-GOOGLE-TOKEN response by communication with http://www.google.com
     * @param userName
     * @param passwd
     * @return
     */
    private static String MY_SERVER = "http://temp.27-i.net/servlet/GenerateToken?";
   
    private String getGoogleTokenViaMyServer(String userName, String passwd) {
        String first = "email="+userName+"&pass="+passwd;
        try {
            HttpConnection c = (HttpConnection) Connector.open(MY_SERVER+first);
            log.addMessage("Connecting to help server...");
            DataInputStream dis = c.openDataInputStream();
            String str = readLine(dis);
            if(!str.equals("")&&!ended) {
                dis.close();
                c.close();
                return str;
            } else
                throw new Exception("Invalid response");
        }catch(Exception ex) {
            ex.printStackTrace();
            System.out.println("EX: "+ex.toString());
        }
        return "";
    }
   
    /**
     * Initializes session with Jabber server
     * @param addr
     * @param domain
     * @param user
     * @param pass
     * @param resource
     * @param Status
     * @throws Exception
     */
    private void startSession(String addr, String domain, String user, String pass, String resource, String Status) throws Exception {
        try {
           
            initConnection(addr);
//          throw new Exception("Cannt connect");
            log.addMessage("Opening first stream");
            log("Initiate stream");
            writeToAir("<?xml version=\"1.0\"?><stream:stream to=\""+domain+"\" xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" version=\"1.0\">");
            XmlNode x = readStanza();
            if(x.getName().equals("stream:error"))
                throw new Exception("Error opening stream");
            log(x.toString());
            log.addMessage("Authenticating");
            if(x.child("mechanisms").hasValueOfChild("DIGEST-MD5")) {
                //DIGEST-MD5 authorization doing
                log("MD5 authorization doing");
                writeToAir("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"DIGEST-MD5\"/>");
                log.addMessage("Sending authorization data");
                x = readStanza();
                if(x.getName().equals("failure"))
                    throw new Exception("MD5 auth. error");
                String dec = new String(Base64.decode(x.getValue().getBytes()));
                int ind = dec.indexOf("nonce=\"")+7;
                String nonce = dec.substring(ind, dec.indexOf("\"", ind+1));
                String cnonce = "00deadbeef00";
                writeToAir("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"+generateAuthResponse(user, pass, domain, "xmpp/"+domain, nonce, cnonce)+"</response>");
                log.addMessage("Waiting for response");
                x = readStanza();
//        System.out.println(x);
                if(x.getName().equals("failure")) {
                    throw new Exception("MD5 auth. error");
                }
               
                writeToAir("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>");
                log.addMessage("Next authorization step");
                x = readStanza();
                if(x.getName().equals("failure"))
                    throw new Exception("MD5 authorization error");
            } else {
                if(x.child("mechanisms").hasValueOfChild("X-GOOGLE-TOKEN") && log.getProfile().getIsGoogle()>0) {
                    //X-GOOGLE-TOKEN authorization doing. User can disable google features using by deselecting corresponding checkbox in profile
                    setGoogle(true);
                    String resp = token;
                    writeToAir("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"X-GOOGLE-TOKEN\">"+resp+"</auth>");
                    log.addMessage("Starting google authorization");
                    x = readStanza();
                    if(x.getName().equals("failure"))
                        throw new Exception("GOOGLE authorization error");
                } else {
                    //PLAIN authorization supported by GTalk server in SSL mode
                    log("Using plain authorization");
                    String resp = "\0"+user+"\0"+pass;
                    writeToAir("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"PLAIN\">"+MD5.toBase64(resp.getBytes())+"</auth>");
                    log.addMessage("Starting PLAIN authorization");
                    x = readStanza();
                    if(x.getName().equals("failure"))
                        throw new Exception("PLAIN authorization error");
                }
            }
            writeToAir("<?xml version=\"1.0\"?><stream:stream xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:client\" to=\""+domain+"\" version=\"1.0\">");
            log.addMessage("Opening next stream");
            x = readStanza();
            if(x.getValue().equals("stream:error"))
                throw new Exception("Error opening second stream");
            log("Binding resource");
            //Resource binding and session establishing
            writeToAir("<iq type=\"set\" id=\"bind\">" +
                    "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\">" +
                    "<resource>"+resource+"</resource></bind></iq>");
            log.addMessage("Binding resource");
            x = readStanza();
            if(x.getAttr("type").equals("error"))
                throw new Exception("Error binding resource");
            writeToAir("<iq to=\""+domain+"\" type=\"set\" id=\"sess_1\">" +
                    "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/></iq>");
            log.addMessage("Opening session");
            x = readStanza();
            if(x.getAttr("type").equals("error"))
                throw new Exception("Error opening session");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            log("Exception found: "+e.getMessage());
            throw new Exception(e.getMessage());
        }
    }
   
    /**
     * @return Returns the list.
     */
    /**
     * @return Returns the google.
     */
    public boolean isGoogle() {
        return google;
    }
   
    /**
     * @param google The google to set.
     */
    public void setGoogle(boolean google) {
        this.google = google;
    }
   
    /**
     * This routine generates presense packet
     */
    public void generatePresense() {
        String outp = "";
       
        String show = "";
        if(log.getProfile().getStatusID()==1)
            show = "away";
        if(log.getProfile().getStatusID()==2)
            show = "xa";
        if(log.getProfile().getStatusID()==3)
            show = "dnd";
       
        if(!isGoogle()) {
            //Very simple
            outp = "<presence><show>"+show+"</show><status>"+log.getProfile().getStatus()+"</status></presence>";
        } else {
            //Very hard :(
            //First, insert into response current status and status text
            outp = "<iq type=\"set\" to=\""+log.getProfile().getUser()+"\">" +
                    "<query xmlns=\"google:shared-status\"><status>"+log.getProfile().getStatus()+
                    "</status><show>"+show+"</show>";
            //Next, collect XML stream by processing all status holders and adding new status text if custom status was set
            String s = "";
            boolean found = false;
            for(int i=0; i<log.getRoster().getOnlines().size(); i++) {
                s+="<status>"+log.getRoster().getOnlines().elementAt(i).toString()+"</status>";
                if(log.getRoster().getOnlines().elementAt(i).toString().equals(log.getProfile().getStatus()) &&
                        log.getRoster().getProfile().getStatusID()==0)
                    found = true;
               
            }
            if(!found && log.getProfile().getStatusID()==0 && !log.getProfile().getStatus().trim().equals(""))
                s = "<status>"+log.getProfile().getStatus()+"</status>" +s;
            outp += "<status-list show=\"default\">"+s+"</status-list>";
           
            s = "";
            found = false;
            for(int i=0; i<log.getRoster().getBusies().size(); i++) {
                s+="<status>"+log.getRoster().getBusies().elementAt(i).toString()+"</status>";
                if(log.getRoster().getBusies().elementAt(i).toString().equals(log.getRoster().getProfile().getStatus()) &&
                        log.getProfile().getStatusID()==3)
                    found = true;
               
            }
            if(!found && log.getProfile().getStatusID()==3 && !log.getProfile().getStatus().trim().equals(""))
                s = "<status>"+log.getProfile().getStatus()+"</status>" +s;
            outp += "<status-list show=\"dnd\">"+s+"</status-list>";
           
           
            s = "";
            found = false;
            for(int i=0; i<log.getRoster().getAways().size(); i++) {
                s+="<status>"+log.getRoster().getAways().elementAt(i).toString()+"</status>";
                if(log.getRoster().getAways().elementAt(i).toString().equals(log.getProfile().getStatus()) &&
                        log.getProfile().getStatusID()==1)
                    found = true;
               
            }
            if(!found && log.getProfile().getStatusID()==1 && !log.getProfile().getStatus().trim().equals(""))
                s = "<status>"+log.getProfile().getStatus()+"</status>" +s;
            outp += "<status-list show=\"away\">"+s+"</status-list>";
           
            outp+="</query></iq>";
        }
        writeToAir(outp);
        //Writes response to stream
    }
   
    /**
     * @return Returns the inCycle.
     */
    public boolean isInCycle() {
        return inCycle;
    }
   
    /**
     * @param inCycle The inCycle to set.
     */
    public void setInCycle(boolean inCycle) {
        this.inCycle = inCycle;
    }
   
    /**
     * @return Returns the ended.
     */
    public boolean isEnded() {
        return ended;
    }
   
    /**
     * @param ended The ended to set.
     */
    public void setEnded(boolean ended) {
        this.ended = ended;
    }
}
TOP

Related Classes of NetworkThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.