package com.safemobile.services; import java.io.*; import java.net.*; import java.nio.charset.Charset; import java.util.LinkedList; import java.util.NoSuchElementException; import java.util.Timer; import java.util.TimerTask; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.wifi.WifiManager; import com.safemobile.lib.AppParams; import com.safemobile.lib.SM; import com.safemobile.lib.TCPmsg; public class TCPhandler implements Runnable { private boolean alive = true; public String serverHostname = new String ("10.120.1.114");// private int port = 13579; private Thread listenThread; private Socket soc =null; //private BufferedReader recv; //private PrintWriter writer; private DataInputStream input; private DataOutputStream output; private Timer timer; private String leftOver = ""; public static LinkedList msgList; private volatile int n=0; public Boolean isConnectionUP = false; public Boolean previousConnectionWasUP = false; private Context context; private boolean isWiFiOn = true; public TCPhandler(Context context, String hostName, int p) { this.context = context; serverHostname=hostName; port=p; msgList = new LinkedList(); SM.Debug("---TCPhandler constructor [" + hostName + "," + p + "] ---"); listenThread = new Thread(this, "TCPlisten"); listenThread.start(); // (2) Start the thread. // create timer to check socket status timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { try { //Looper.prepare(); //mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // get if is authenticated //Write("0.0", "d"); previousConnectionWasUP = isConnectionUP; // try to send something TCPmsgParser._fireonTCPConnectionStatusEvent(isConnectionUP, previousConnectionWasUP); } catch (Exception e) { //e.printStackTrace(); SM.Exception("TIMERException", e.toString()); } } }, 0, 3000); // get WiFi state ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); if(mWifi.isConnectedOrConnecting()) isWiFiOn = true; IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); context.registerReceiver(mReceived, intentFilter); } @Override public void run() { try { if(soc!=null) soc.close(); soc = new Socket(); soc.connect(new InetSocketAddress(serverHostname, port), 5000); //soc.setSoTimeout(3000); //SM.Debug("Socket timeout:" + soc.getSoTimeout() ); //soc.setSoTimeout(5000); input = new DataInputStream(soc.getInputStream()); output = new DataOutputStream(soc.getOutputStream()); //recv= new BufferedReader(new InputStreamReader(soc.getInputStream())); //writer =new PrintWriter(soc.getOutputStream()) ; if(soc !=null) { //previousConnectionWasUP = isConnectionUP; isConnectionUP = true; triggerTCPConnectionStateEvent(); } } catch (UnknownHostException e) { SM.Debug("UnknownHostException", "TCPhandler break:"+e.toString()); } catch (IllegalArgumentException e) { SM.Debug("IllegalArgumentException", "TCPhandler break:"+e.toString()); } catch (IOException e) { SM.Debug("IOException", "TCPhandler break:"+e.toString()); } while(alive) { //SM.Debug("Waiting for data..."); try { Thread.sleep(3000); } catch (InterruptedException e) { SM.Debug("TCPhandler Crash1 on sleep:"+e.toString()); } while(isConnectionUP) { try { Thread.sleep(100); //SM.Debug("Waiting for data..."); //process leftover try { boolean FinishLeftOver =true; while (FinishLeftOver) { // add this replacement if message length doesn't contain the last # // leftOver = leftOver.replace("##", "#"); String[] tempArr2 = leftOver.split("#"); if (tempArr2.length > 1) { int messLen; try { messLen = Integer.parseInt(tempArr2[1]); //TODO talk to Gaby to fix this on Bridge } catch (Exception e) { SM.Debug("leftovers", "incorect msg len leftOver =" + tempArr2[1]); messLen =-1; } if(messLen>leftOver.length()) { FinishLeftOver =false; break; } else if(messLen==leftOver.length()) { TCPmsg msg = new TCPmsg(leftOver.toCharArray()); SM.Debug("leftovers", "RX from leftOver:"+msg.allData); if(msg.allData.contains("#92#")) prioritizePongReceived(); msgList.add(msg); leftOver =""; FinishLeftOver =false; break; } else // we have more message in leftover { TCPmsg msg = new TCPmsg(leftOver.substring(0,messLen).toCharArray()); SM.Debug("leftovers", "RX from leftOver:"+msg.allData); if(msg.allData.contains("#92#")) prioritizePongReceived(); msgList.add(msg); leftOver = leftOver.substring(messLen,leftOver.length()); } } else FinishLeftOver = false; } } catch (Exception e) { SM.Debug("leftovers", "Error on process leftover"+e.toString()); } //end process leftover String data =""; n=0; //char[] buf = new char[1024]; //n = recv.read(buf); byte[] buf = new byte[1024]; // read data into buffer n = input.read(buf); //connection closed by server if(n==-1) { SM.Debug("TCP Client", "Connection closed by server!"); soc.close(); //previousConnectionWasUP = isConnectionUP; isConnectionUP = false; triggerTCPConnectionStateEvent(); soc = null; break; } byte[] temp = new byte[n]; for(int i=0;i1) // avoid case with only one # { data = leftOver+data; leftOver = ""; } //search for overflow message String[] tempArr = data.split("#"); if ((tempArr.length == 0) || (tempArr.length == 1)) { SM.Debug("TCP Client", "incorect messagebuss message=" + data); continue; } //get msg len // for(int i=0;idata.length()) //if(messLen>n) { //SM.Debug("duda","messLen=" + messLen +" data.length():" +data.length()+"n:"+n); leftOver = data; // Add by bigu continue; } //perform cut //SM.Debug("We got leftover ....message length("+messLen+") != actual length("+data.length()+")"); temMSG = data.substring(0,messLen).toCharArray(); //SM.Debug("temMSG:"+temMSG.toString()); leftOver = data.substring(messLen,data.length()); //SM.Debug("leftOver:"+leftOver); //leftOver = data.substring(messLen,n); //SM.Debug("left over string:"+leftOver); } //decode TCP msg TCPmsg msg = new TCPmsg(temMSG); SM.Debug("������� RX �������", msg.allData); if(msg.allData.contains("#92#")) prioritizePongReceived(); msgList.add(msg); } catch(Exception ex) { SM.Debug("TCPHandler", "TCPhandler/run/break:"+ex.toString()); //previousConnectionWasUP = isConnectionUP; isConnectionUP = false; triggerTCPConnectionStateEvent(); } }//while(connOK) // try { Thread.sleep(1000); } catch (InterruptedException e) { SM.Debug("TCPhandler Crash2 on sleep:"+e.toString()); //previousConnectionWasUP = isConnectionUP; } //try to restart connection if(alive && isWiFiOn) RestartTCP(); }//while(alive) SM.Debug("=================================="); SM.Debug("TCP listenThread stoped!! alive = false"); SM.Debug("=================================="); } /** * Create a bypass in order to trigger the ping received event */ private void prioritizePongReceived() { TCPmsgParser._firePONGReceivedEvent(); } /* Broadcast Received for WiFi Connect/Disconnect */ public BroadcastReceiver mReceived = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); SM.Debug("WIFI STATE", action); if(action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){ NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); // close socket if the wifi is disconnecting or disconnected if(!info.isConnectedOrConnecting()) { closeSocket(); isWiFiOn = false; } else isWiFiOn = true; } } }; /** Send a message through the TCP Socket * @param seqID The messages's sequence ID (a number of order) * @param msg The messages which will be sent * @return True if the message was sent */ public boolean Write(String seqID, String msg) { try { /* if(writer != null) { String cmdok = "#" + seqID + msg; Integer tmp = cmdok.length() + 1; //SM.Debug("tmp:"+tmp); tmp += Integer.toString(tmp).length();// tmp.ToString().Length; if((tmp==10)||(tmp==100)||(tmp==1000)) tmp++; cmdok = "#" + Integer.toString(tmp) + cmdok; writer.write(encryptTEA(cmdok)); writer.flush(); SM.Debug("TX:"+encryptTEA(cmdok)); return true; }*/ if(output != null) { try { Thread.sleep(10); String cmdok = "#" + seqID + msg; Integer tmp = cmdok.length() + 1; //SM.Debug("tmp:"+tmp); tmp += Integer.toString(tmp).length();// tmp.ToString().Length; if((tmp==10)||(tmp==100)||(tmp==1000)) tmp++; cmdok = "#" + Integer.toString(tmp) + cmdok; byte[] mess = encryptTEA(cmdok); output.write(mess); output.flush(); // show only notACK messages //if(mess[3] != 0x0C) SM.Debug(" ", new String(mess)); return true; } catch (IOException e) { //e.printStackTrace(); SM.Exception("TCPClient[Send]", e.toString()); } catch (InterruptedException e) { SM.Exception("TCPClient[Send]", e.toString()); } catch (NoSuchElementException e) { SM.Exception("TCPClient[Send]", e.toString()); } } else { return false; } } catch (Exception e) { SM.Debug("TCPhandler Write Procedure:"+e.toString()); } return false; } public void setConnectionIsDown() { if(input != null) { try { input.close(); } catch (IOException e) { } finally { input = null; } } isConnectionUP = false; } /* Encrypt a string using an encryption algorithm, * in this case TEA */ public static byte[] encryptTEA(String toEncryptData) { byte[] encryptedByteArray = new byte[]{}; /* //encrypt message using TEA try { encryptedByteArray = TEA.encrypt(toEncryptData); } catch (UnsupportedEncodingException e) { SM.Exception("encryptTEA Exception(UEE): " + e.toString()); } catch (IndexOutOfBoundsException e) { SM.Exception("encryptTEA Exception(IOoBE): " + e.toString()); } catch (NullPointerException e) { SM.Exception("encryptTEA Exception(NPE): " + e.toString()); } //*/ // no encryption encryptedByteArray = toEncryptData.getBytes(); return encryptedByteArray; } /* Decrypt a string using an encryption algorithm, * in this case TEA */ public static byte[] decryptTEA(byte[] toDecryptData) { byte[] decryptedByteArray = new byte[]{}; /* String sm = ""; for(int i=0; i