Android Open Source - android_smsoverxmpp Client






From Project

Back to project page android_smsoverxmpp.

License

The source code is released under:

GNU General Public License

If you think the Android project android_smsoverxmpp listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.smorra.smsoverxmpp;
//from  www  .  j a va  2 s .c o m
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLEngineResult.Status;
import javax.net.ssl.SSLException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.util.Base64;
import android.widget.Toast;

import com.smorra.asyncsocket.TcpServerClient;
import com.smorra.asyncsocket.TcpServerClientCallback;

public class Client extends Handler implements TcpServerClientCallback
{

  TcpServerClient tsc;
  byte[] buffer = new byte[0];
  byte[] decodedBuffer = new byte[0];
  boolean isClosed;
  Server server;
  boolean isAuthed = false;
  ArrayList<String> usedIds = new ArrayList<String>();

  boolean isStreamClosed;

  enum State
  {
    BEFORE_HANDSHAKE, HANDSHAKING, AFTER_HANDSHAKE
  }

  State state = State.BEFORE_HANDSHAKE;
  String to = null;
  boolean isSslStreamRead = false;

  SSLEngine engine;
  String bindId;
  Context context;

  public Client(TcpServerClient tsc, Server server, Context context) throws IOException, InterruptedException
  {
    this.server = server;
    this.tsc = tsc;
    this.context = context;
    tsc.setCallbackInterface(this);

    // tsc.write("<?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='jabber.b4ne.de' id='6d5778d5-39ad-4d48-b01d-4a6bb52453da' xml:lang='en' xmlns='jabber:client'><stream:features><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>SCRAM-SHA-1</mechanism><mechanism>PLAIN</mechanism></mechanisms></stream:features>".getBytes());
  }

  public void close() throws IOException
  {
    tsc.close();
  }

  @Override
  public void onRead(TcpServerClient tc, byte[] bytes)
  {
    try
    {
      System.out.println("onread " + new String(bytes, "UTF-8"));
    }
    catch (UnsupportedEncodingException e1)
    {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    }
    byte[] new_buffer = new byte[bytes.length + buffer.length];
    System.arraycopy(buffer, 0, new_buffer, 0, buffer.length);
    System.arraycopy(bytes, 0, new_buffer, buffer.length, bytes.length);
    buffer = new_buffer;

    while (state == State.BEFORE_HANDSHAKE)
    {

      try
      {
        System.out.println("BUFFER IS " + new String(buffer, "UTF-8"));
      }
      catch (UnsupportedEncodingException e1)
      {
        // TODO Auto-generated catch block
        e1.printStackTrace();
      }
      int i;
      for (i = 0; i < buffer.length; i++)
      {
        if (buffer[i] == '>')
        {
          byte[] cmd = new byte[i + 1];
          System.arraycopy(buffer, 0, cmd, 0, i + 1);
          new_buffer = new byte[buffer.length - i - 1];
          System.arraycopy(buffer, i + 1, new_buffer, 0, new_buffer.length);
          buffer = new_buffer;
          try
          {
            System.out.println("HANDLESTREAM BEGIN \"" + new String(cmd, "UTF-8") + "\"");
            handleStreamBegin(cmd);
          }
          catch (Exception e)
          {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
          break;
        }
      }
      if (i == buffer.length)
        break;
    }

    boolean enoughBytesForUnwrap = true;
    while (state == State.HANDSHAKING)
    {
      if (engine.getHandshakeStatus() == HandshakeStatus.NEED_UNWRAP)
      {
        if (!enoughBytesForUnwrap)
          break;
        int bufSize = engine.getSession().getApplicationBufferSize();
        System.out.println("ENTER LOOP");
        while (true)
        {
          ByteBuffer dst = ByteBuffer.allocate(bufSize);
          ByteBuffer src = ByteBuffer.wrap(buffer);
          SSLEngineResult res = null;
          try
          {
            res = engine.unwrap(src, dst);
          }
          catch (Exception e)
          {
            e.printStackTrace();
          }

          // process produced bytes
          byte[] decoded = new byte[res.bytesProduced()];
          System.arraycopy(dst.array(), 0, decoded, 0, decoded.length);
          try
          {
            System.out.println("CALLIGN FROM LINE XYZ2");
            doReadDecoded(decoded);
          }
          catch (Exception e)
          {
            e.printStackTrace();
          }

          new_buffer = new byte[src.capacity() - src.position()];
          System.arraycopy(buffer, src.position(), new_buffer, 0, new_buffer.length);
          buffer = new_buffer;

          if (res.getStatus() == Status.BUFFER_OVERFLOW)
          {
            System.out.println("BUFFER OVERFLOW");
            bufSize += 1024;
          }
          else if (res.getStatus() == Status.BUFFER_UNDERFLOW || res.getStatus() == Status.CLOSED)
          {
            System.out.println("BUFFER UNDERFLOW or CLOSED");
            enoughBytesForUnwrap = false;
            break;
          }
          else if (res.getStatus() == Status.OK)
          { // do it again
            if (res.bytesConsumed() == 0)
            {
              enoughBytesForUnwrap = false;
              break;
            }
            bufSize = engine.getSession().getApplicationBufferSize();
          }
        }
      }
      else if (engine.getHandshakeStatus() == HandshakeStatus.NEED_TASK)
      {
        Runnable runnable = engine.getDelegatedTask();
        runnable.run();
      }
      else if (engine.getHandshakeStatus() == HandshakeStatus.NEED_WRAP)
      {
        int bufSize = engine.getSession().getPacketBufferSize();
        while (engine.getHandshakeStatus() == HandshakeStatus.NEED_WRAP)
        {
          System.out.println("IN OOOOOOP");
          ByteBuffer src = ByteBuffer.allocate(0);
          ByteBuffer dst = ByteBuffer.allocate(bufSize);

          SSLEngineResult res = null;
          try
          {
            res = engine.wrap(src, dst);
          }
          catch (SSLException e)
          {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Toast.makeText(context, "Client incompatible. Please try a different client.", Toast.LENGTH_LONG).show();
            try
            {
              handleStreamClose();
            }
            catch (IOException e1)
            {
              // TODO Auto-generated catch block
              e1.printStackTrace();
            }
            return;

          }

          // process produced bytes
          byte[] produced = new byte[res.bytesProduced()];
          System.arraycopy(dst.array(), 0, produced, 0, produced.length);
          try
          {
            write(produced);
          }
          catch (IOException e)
          {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
          System.out.println("RESULT IS " + res.getStatus());
          if (res.getStatus() == Status.BUFFER_OVERFLOW)
          {
            bufSize += 1024;
          }
          else if (res.getStatus() == Status.OK)
          {
            bufSize = engine.getSession().getApplicationBufferSize();
          }
          else if (res.getStatus() == Status.CLOSED)
          {
            System.out.println("WHAT TO DO?");
          }
          else if (res.getStatus() == Status.BUFFER_UNDERFLOW)
          {
            System.out.println("BUFFER_UNDERFLOW while wrapping?");
          }

        }

      }
      else
      {
        state = State.AFTER_HANDSHAKE;
        System.out.println("UNKNOWN STATE " + engine.getHandshakeStatus());
        break;
      }

    }

    if (state == State.AFTER_HANDSHAKE)
    {

      int bufSize = engine.getSession().getApplicationBufferSize();

      while (true)
      {
        System.out.println("IN LOOP AFTER");
        ByteBuffer dst = ByteBuffer.allocate(bufSize);
        ByteBuffer src = ByteBuffer.wrap(buffer);

        SSLEngineResult res = null;
        try
        {
          res = engine.unwrap(src, dst);
        }
        catch (SSLException e1)
        {
          // TODO Auto-generated catch block
          e1.printStackTrace();
        }

        // process produced bytes
        byte[] decoded = new byte[res.bytesProduced()];
        System.arraycopy(dst.array(), 0, decoded, 0, decoded.length);
        try
        {
          System.out.println("CALLIGN FROM LINE XY");
          doReadDecoded(decoded);
        }
        catch (Exception e)
        {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }

        // refresh buffer
        new_buffer = new byte[buffer.length - res.bytesConsumed()];
        System.arraycopy(buffer, res.bytesConsumed(), new_buffer, 0, new_buffer.length);
        buffer = new_buffer;

        if (res.getStatus() == Status.BUFFER_OVERFLOW)
        {
          bufSize += 1024;
        }
        else if (res.getStatus() == Status.BUFFER_UNDERFLOW || res.getStatus() == Status.CLOSED)
        {
          break;
        }
        else if (res.getStatus() == Status.OK)
        {
          if (res.bytesConsumed() == 0)
            break;
          // do it again
          bufSize = engine.getSession().getApplicationBufferSize();
        }

      }

    }

  }

  private void doReadDecoded(byte[] dat) throws IOException, ParserConfigurationException, SAXException
  {
    if (isStreamClosed)
      return;
    try
    {
      System.out.println("READING DECODED: " + new String(dat, "UTF-8"));
    }
    catch (UnsupportedEncodingException e)
    {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    System.out.println("CALL TO doReadDecoded");
    byte[] new_decodedBuffer = new byte[decodedBuffer.length + dat.length];
    System.arraycopy(decodedBuffer, 0, new_decodedBuffer, 0, decodedBuffer.length);
    System.arraycopy(dat, 0, new_decodedBuffer, decodedBuffer.length, dat.length);
    decodedBuffer = new_decodedBuffer;

    boolean found = true;
    while (found)
    {

      found = false;
      for (int i = 0; i < decodedBuffer.length; i++)
      {
        if (decodedBuffer[i] == '>')
        {
          byte[] cmd = new byte[i + 1];
          System.arraycopy(decodedBuffer, 0, cmd, 0, cmd.length);
          cmd = unpadCmd(cmd);
          if (new String(cmd, "UTF-8").startsWith("</stream:stream>"))
          {
            handleStreamClose();
            break;
          }
          if (new String(cmd, "UTF-8").startsWith("<stream:stream ") || new String(cmd, "UTF-8").startsWith("<?xml "))
          {
            byte[] new_decodeBuffer = new byte[decodedBuffer.length - i - 1];
            System.arraycopy(decodedBuffer, i + 1, new_decodeBuffer, 0, new_decodeBuffer.length);
            decodedBuffer = new_decodeBuffer;
            handleStreamSsl(cmd);
            found = true;
            break;
          }
          try
          {
            String test = new String(cmd, "UTF-8");
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(test));
            db.parse(is);
            found = true;
            byte[] new_decodeBuffer = new byte[decodedBuffer.length - i - 1];
            System.arraycopy(decodedBuffer, i + 1, new_decodeBuffer, 0, new_decodeBuffer.length);
            decodedBuffer = new_decodeBuffer;

            try
            {
              handleCommandSsl(test);
            }
            catch (Exception e)
            {
              e.printStackTrace();
            }
            break;
          }
          catch (Exception e)
          {

          }

        }
      }

      System.out.println("DOREADDECODED " + dat.length);

    }
  }

  private byte[] unpadCmd(byte[] cmd)
  {
    int i = 0;
    for (; i < cmd.length; i++)
    {
      if (cmd[i] == '<')
        break;
    }
    byte[] cmd_new = new byte[cmd.length - i];
    System.arraycopy(cmd, i, cmd_new, 0, cmd_new.length);
    return cmd_new;
  }

  private void handleStreamSsl(byte[] cmd) throws IOException, ParserConfigurationException, SAXException
  {
    String cmd_ = new String(cmd, "UTF-8");

    System.out.println("handleStreamSsl " + cmd_);
    if (cmd_.startsWith("<stream:stream "))
    {
      Document doc = null;
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      InputSource is = new InputSource();
      is.setCharacterStream(new StringReader(cmd_ + "</stream:stream>"));
      doc = db.parse(is);
      to = ((Element) doc.getFirstChild()).getAttributeNode("to").getValue();
      writeSsl("<?xml version='1.0'?>".getBytes());
      if (isAuthed)
      {
        writeSsl(("<stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='" + to + "' id='" + generateId() + "' xml:lang='en' xmlns='jabber:client'>)").getBytes());
        writeSsl("<stream:features>".getBytes());
        writeSsl("<ver xmlns='urn:xmpp:features:rosterver'/>".getBytes());
        writeSsl("<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><required/></bind>".getBytes());
        writeSsl("<session xmlns='urn:ietf:params:xml:ns:xmpp-session'><optional/></session>".getBytes());
        writeSsl("</stream:features>".getBytes());
      }
      else
      {
        writeSsl(("<stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='" + to + "' id='" + generateId() + "' xml:lang='en' xmlns='jabber:client'>").getBytes());
        writeSsl("<stream:features>".getBytes());
        writeSsl("<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>".getBytes());
        writeSsl("<mechanism>PLAIN</mechanism>".getBytes());
        writeSsl("</mechanisms>".getBytes());
        writeSsl("</stream:features>".getBytes());
      }
      isSslStreamRead = true;
    }
    else if (cmd_.startsWith("<?xml "))
    {

    }

  }

  private String generateId()
  {
    String candidate = Util.generateHex(8) + "-" + Util.generateHex(4) + "-" + Util.generateHex(4) + "-" + Util.generateHex(8);
    for (String str : usedIds)
    {
      if (str.equals(candidate))
        return generateId();
    }
    usedIds.add(candidate);
    return candidate;
  }

  private void handleStreamClose() throws IOException
  {
    isStreamClosed = true;
    System.out.println("HANDLE STREAM CLOSE");
    tsc.close();
    server.removeClient(this);
  }

  private void handleCommandSsl(String s) throws ParserConfigurationException, SAXException, IOException
  {
    System.out.println("handleCommandSsl: " + s);

    Document doc = null;
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    InputSource is = new InputSource();
    is.setCharacterStream(new StringReader(s));
    doc = db.parse(is);

    Element first = (Element) doc.getFirstChild();

    if (first.getNodeName().equals("presence"))
    {
      return;
    }
    if (first.getNodeName().equals("auth"))
    {
      String str = first.getTextContent();
      byte[] userpw = Base64.decode(str, Base64.DEFAULT);
      String user = "", pw = "";
      for (int i = 1; i < userpw.length; i++)
      {
        if (userpw[i] == 0)
        {

          user = new String(userpw, 1, i - 1);
          pw = new String(userpw, i + 1, userpw.length - i - 1);
          System.out.println("PW: " + pw);
          System.out.println("user: " + user);
          break;
        }
      }
      if (user.equals("android") && pw.equals(Util.getPw(context)))
      {
        isAuthed = true;
        writeSsl("<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'></success>".getBytes());

        return;
      }
      else
      {
        writeSsl("<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><not-authorized/><text>Unable to authorize you with the authentication credentials you&apos;ve sent.</text></failure>".getBytes());
        System.out.println("Wrong login. User: " + user + " Password: " + pw);
        return;
      }
    }
    else if (first.getNodeName().equals("message"))
    {
      Node type = first.getAttributes().getNamedItem("type");
      Node to = first.getAttributes().getNamedItem("to");
      if (to != null && type != null && type.getNodeValue().equals("chat"))
      {
        Node body = first.getElementsByTagName("body").item(0);
        if (body != null)
        {
          String body_ = body.getTextContent();
          String to_ = to.getNodeValue();
          String number = to_.substring(0, to_.indexOf('@'));
          Util.sendSms(number, body_);

          ContentValues content = new ContentValues();
          content.put("address", number);
          content.put("body", body_);
          context.getContentResolver().insert(Uri.parse("content://sms/sent"), content);
        }
      }
      return;
    }
    else if (first.getNodeName().equals("iq"))
    {
      Element second = (Element) doc.getFirstChild().getFirstChild();

      String id = first.getAttributes().getNamedItem("id").getNodeValue();
      Node toAttr = first.getAttributes().getNamedItem("to");
      String toStr = toAttr == null ? to : toAttr.getNodeValue();
      if (first.getAttributes().getNamedItem("type").getNodeValue().equals("set"))
      {
        if (second.getNodeName().equals("bind"))
        {
          bindId = generateId();
          writeSsl(("<iq id='" + id + "' type='result'>").getBytes());
          writeSsl("<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>".getBytes());
          writeSsl(("<jid>android@" + to + "/" + bindId + "</jid>").getBytes());
          writeSsl("</bind>".getBytes());
          writeSsl("</iq>".getBytes());
          sendUnreadSms();
          ContentValues values = new ContentValues();
          values.put("read", 1);
          context.getContentResolver().update(Uri.parse("content://sms/inbox"), values, null, null);
          return;

        }
        else if (second.getNodeName().equals("session"))
        {
          writeSsl(("<iq id='" + id + "' type='result' to='android@" + to + "/" + generateId() + "'/>").getBytes());
          return;

        }
      }
      else if (first.getAttributes().getNamedItem("type").getNodeValue().equals("get"))
      {
        if (second.getNodeName().equals("query"))
        {
          String xmlns = second.getAttributes().getNamedItem("xmlns").getNodeValue();
          if (xmlns.equals("http://jabber.org/protocol/disco#items"))
          {
            writeSsl(("<iq id='" + id + "' type='result' to='android@" + to + "/" + bindId + "' from='" + toStr + "'>").getBytes());
            writeSsl("<query xmlns='http://jabber.org/protocol/disco#items'/>".getBytes());
            writeSsl("</iq>".getBytes());
            return;

          }
          else if (xmlns.equals("http://jabber.org/protocol/disco#info"))
          {
            writeSsl(("<iq id='" + id + "' type='result' to='android@" + to + "/" + bindId + "' from='" + toStr + "'>").getBytes());
            writeSsl("<query xmlns='http://jabber.org/protocol/disco#info'>".getBytes());
            writeSsl("<feature var='jabber:iq:roster'/>".getBytes());
            writeSsl("</query>".getBytes());
            writeSsl("</iq>".getBytes());
            return;

          }
          else if (xmlns.equals("jabber:iq:roster"))
          {
            writeSsl(("<iq id='" + id + "' type='result' to='android@" + to + "/" + bindId + "'>").getBytes());
            writeSsl("<query xmlns='jabber:iq:roster'>".getBytes());

            ArrayList<Contact> contacts = Util.getContacts(context);
            for (Contact contact : contacts)
            {
              writeSsl(("<item jid='" + contact.number + "@" + to + "' subscription='both' name='" + contact.name + "'></item>").getBytes());

            }

            writeSsl("</query>".getBytes());
            writeSsl("</iq>".getBytes());
            for (Contact contact : contacts)
            {
              writeSsl(("<presence from='" + contact.number + "@" + to + "/SMS' to='andriod@" + to + "'/>").getBytes());
            }
            return;

          }
        }
        else if (second.getNodeName().equals("vCard"))
        {
          writeSsl(("<iq id='" + id + "' type='result' to='android@" + to + "/" + bindId + "' from='" + toStr + "'>").getBytes());
          writeSsl(("<vCard xmlns='vcard-temp'><NICKNAME>android@" + to + "</NICKNAME></vCard>").getBytes());
          writeSsl("</iq>".getBytes());
          return;
        }
        else if (second.getNodeName().equals("ping"))
        {
          writeSsl(("<iq id='" + id + "' type='result' to='android@" + to + "/" + bindId + "'/>").getBytes());
          return;
        }
      }
      if (toStr != null)
        writeSsl(("<iq from='" + toStr + "' id='" + id + "' type='error' to='android@" + to + "/" + generateId() + "'/>").getBytes());
      return;
    }
    System.out.println("WARNING ! COMMAND NOT HANDLED");

  }

  private void writeSsl(byte[] bytes) throws IOException
  {

    int bufSize = engine.getSession().getApplicationBufferSize();
    while (bytes.length != 0)
    {
      ByteBuffer src = ByteBuffer.wrap(bytes);
      ByteBuffer dst = ByteBuffer.allocate(bufSize);
      SSLEngineResult res = engine.wrap(src, dst);

      byte[] produced = new byte[res.bytesProduced()];
      System.arraycopy(dst.array(), 0, produced, 0, res.bytesProduced());
      tsc.write(produced);

      byte[] new_bytes = new byte[bytes.length - res.bytesConsumed()];
      System.arraycopy(bytes, res.bytesConsumed(), new_bytes, 0, new_bytes.length);
      bytes = new_bytes;

      if (res.getStatus() == Status.BUFFER_OVERFLOW)
        bufSize += 1024;

    }

  }

  public boolean sendUnreadSms() throws IOException
  {
    Cursor c = context.getContentResolver().query(Uri.parse("content://sms/inbox"), null, "read = 0", null, null);
    boolean hasNew = false;
    while (c.moveToNext())
    {

      String findNumber = Util.findNumber(c.getString(c.getColumnIndex("address")), context);
      if (findNumber == null)
        findNumber = c.getString(c.getColumnIndex("address"));

      writeSsl(("<message id='some_id' type='chat' from='" + findNumber + "@" + to + "/" + bindId + "'>").getBytes());
      writeSsl(("<body>" + Util.xmlEncode(c.getString(c.getColumnIndex("body"))) + "</body>").getBytes());
      writeSsl("</message>".getBytes());
      hasNew = true;
    }
    c.close();

    return hasNew;
  }

  private void handleStreamBegin(byte[] cmd) throws ParserConfigurationException, SAXException, IOException, NoSuchAlgorithmException
  {
    cmd = unpadCmd(cmd);

    String cmd_ = new String(cmd, "UTF-8");
    if (cmd_.startsWith("<?xml "))
      return;
    if (cmd_.startsWith("<stream:stream "))
    {
      Document doc = null;
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      InputSource is = new InputSource();
      is.setCharacterStream(new StringReader(cmd_ + "</stream:stream>"));
      doc = db.parse(is);
      to = ((Element) doc.getFirstChild()).getAttributeNode("to").getValue();

      write("<?xml version='1.0'?>".getBytes());
      write(("<stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='" + to + "' id='" + generateId() + "' xml:lang='en' xmlns='jabber:client'>").getBytes());
      write("<stream:features>".getBytes());
      write("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required/></starttls>".getBytes());
      write("</stream:features>".getBytes());

      System.out.println("COMMAND " + cmd_);

    }
    else if (cmd_.startsWith("<starttls "))

    {
      write("<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>".getBytes());
      SSLContext sslc = null;

      sslc = SSLContext.getInstance("TLS");

      KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
      try
      {
        kmf.init(Service_.ks, "pw".toCharArray());
        sslc.init(kmf.getKeyManagers(), null, null);
      }
      catch (Exception e)
      {
        e.printStackTrace();
      }
      engine = sslc.createSSLEngine();

      engine.setEnabledCipherSuites(new String[] { "SSL_RSA_WITH_RC4_128_MD5" });
      // engine.setEnabledCipherSuites(new String[] {
      // "SSL_RSA_WITH_RC4_128_SHA" });
      engine.setUseClientMode(false);
      engine.beginHandshake();
      state = State.HANDSHAKING;
      if (engine.getHandshakeStatus() != HandshakeStatus.NEED_UNWRAP)
      {
        throw new IOException("STATUS SHOULD BE NEED_UNWRAP");
      }

    }
  }

  private void write(byte[] bytes) throws IOException
  {
    System.out.println("writing: " + new String(bytes, "UTF-8"));
    tsc.write(bytes);
  }

  @Override
  public void onDisconnect(TcpServerClient tc)
  {
    System.out.println("ON DISCONNECT");
    isClosed = true;
    server.removeClient(this);
  }

  @Override
  public void onWritten(TcpServerClient tcpClient)
  {
  }

  public boolean onSmsReceived() throws IOException
  {
    if (!isAuthed)
      return false;
    return sendUnreadSms();
  }

}




Java Source Code List

com.smorra.smsoverxmpp.BootReceiver.java
com.smorra.smsoverxmpp.Client.java
com.smorra.smsoverxmpp.Contact.java
com.smorra.smsoverxmpp.IpReceiver.java
com.smorra.smsoverxmpp.MainActivity.java
com.smorra.smsoverxmpp.PhoneNumber.java
com.smorra.smsoverxmpp.Server.java
com.smorra.smsoverxmpp.Service_.java
com.smorra.smsoverxmpp.SmsReceiver.java
com.smorra.smsoverxmpp.Util.java