Browse Source

added initial sync data structures

Alexander Brakowski 9 years ago
parent
commit
e1eacb4b7e

+ 1 - 1
.gitignore

@@ -7,7 +7,7 @@
 
 # Java class files
 *.class
-
+*.orig
 # generated files
 bin/
 gen/

+ 4 - 4
AndroidManifest.xml

@@ -49,7 +49,7 @@
             android:value="@string/google_maps_api_key_release" />
 
         <activity
-            android:name=".ui2.activity.MainActivity"
+            android:name=".ui.activity.MainActivity"
             android:configChanges="keyboardHidden|orientation|screenSize"
             android:label="@string/app_name"
             android:screenOrientation="portrait" >
@@ -60,7 +60,7 @@
             </intent-filter>
         </activity>
         <activity
-            android:name=".ui2.activity.ProfileEditActivity"
+            android:name=".ui.activity.ProfileEditActivity"
             android:label="Edit Profile" >
         </activity>
         <activity
@@ -74,7 +74,7 @@
             android:theme="@android:style/Theme.Dialog" >
         </activity>
         <activity
-            android:name=".sync.nfc.NFCSync"
+            android:name=".sync.nfc.NFCSyncActivity"
             android:label="@string/gui_nfc"
             android:theme="@android:style/Theme.Dialog" >
             <intent-filter>
@@ -112,7 +112,7 @@
         <activity
             android:name=".sync.p2p.P2PSyncActivity"
             android:label="@string/title_activity_p2_psync"
-            android:parentActivityName=".ui2.activity.MainActivity" >
+            android:parentActivityName=".ui.activity.MainActivity" >
             <meta-data
                 android:name="android.support.PARENT_ACTIVITY"
                 android:value="de.tudarmstadt.informatik.hostage.ui2.activity.MainActivity" />

+ 13 - 0
src/de/tudarmstadt/informatik/hostage/logging/SyncData.java

@@ -0,0 +1,13 @@
+package de.tudarmstadt.informatik.hostage.logging;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class SyncData implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Contains a list of records with should be sent to synchronize
+     */
+    public List<Record> records;
+}

+ 25 - 0
src/de/tudarmstadt/informatik/hostage/logging/SyncInfo.java

@@ -0,0 +1,25 @@
+package de.tudarmstadt.informatik.hostage.logging;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+public class SyncInfo implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The first Message that should be sent when two devices want to synchronize.
+     * It should contain a Map of devices and either the latest attack ID the device has in the database
+     * or the time of the latest attack.
+     *
+     *
+     * | A -> SyncInfo -> B |
+     * |                    | ----- SyncInfo independent
+     * | A <- SyncInfo <- B |
+     *
+     *
+     * Now A looks what it has that B does not have, by comparing the device ID's and the newest entry indicator,
+     * and sends it to B. (SyncData object)
+     * B does the same, now these two devices should be synchronized.
+     */
+    public HashMap<String, Long> deviceMap;
+}

+ 2 - 0
src/de/tudarmstadt/informatik/hostage/sync/p2p/P2PBroadcastReceiver.java

@@ -38,6 +38,8 @@ public class P2PBroadcastReceiver extends BroadcastReceiver {
 
             if(networkInfo.isConnected()){
                 mManager.requestConnectionInfo(mChannel, mActivity);
+            } else {
+                mActivity.closeConnection();
             }
         } else if(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)){
             WifiP2pDevice device = (WifiP2pDevice) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);

+ 113 - 31
src/de/tudarmstadt/informatik/hostage/sync/p2p/P2PSyncActivity.java

@@ -11,26 +11,25 @@ import android.net.wifi.p2p.WifiP2pGroup;
 import android.net.wifi.p2p.WifiP2pInfo;
 import android.net.wifi.p2p.WifiP2pManager;
 import android.os.AsyncTask;
-import android.os.Build;
 import android.os.Bundle;
-import android.os.Environment;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
-import android.widget.Button;
 import android.widget.ListView;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 import android.widget.Toast;
 import android.widget.ViewAnimator;
 
-import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.InetSocketAddress;
@@ -41,7 +40,7 @@ import java.util.List;
 
 import de.tudarmstadt.informatik.hostage.R;
 
-public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerListListener, WifiP2pManager.ChannelListener, AdapterView.OnItemClickListener, WifiP2pManager.ConnectionInfoListener {
+public class P2PSyncActivity extends Activity implements WifiP2pManager.GroupInfoListener, WifiP2pManager.PeerListListener, WifiP2pManager.ChannelListener, AdapterView.OnItemClickListener, WifiP2pManager.ConnectionInfoListener {
     private WifiP2pManager mManager;
     private WifiP2pManager.Channel mChannel;
     private BroadcastReceiver mReceiver;
@@ -66,6 +65,9 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
     private final int OWNER_SERVER_PORT = 8988;
     private final int CLIENT_SERVER_PORT = 8989;
 
+    private ClientAsyncTask clientAsync;
+    private ServerAsyncTask serverAsync;
+
     private void extractFromView(){
         mTxtP2PDeviceName = (TextView) findViewById(R.id.txt_p2p_device_name);
         mTxtP2PDeviceStatus = (TextView) findViewById(R.id.txt_p2p_device_status);
@@ -105,6 +107,9 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
     public void setWifiDirectNotAvailable(){
         //mBtnP2PSearch.setVisibility(View.GONE);
         mTxtP2PNotAvailable.setVisibility(View.VISIBLE);
+        peers.clear();
+        ((WiFiPeerListAdapter) mLstP2PDevices.getAdapter()).notifyDataSetChanged();
+        mDevice = null;
     }
 
     public void setWifiDirectAvailable(){
@@ -112,6 +117,16 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
         mTxtP2PNotAvailable.setVisibility(View.GONE);
     }
 
+    public void closeConnection(){
+        if(this.serverAsync != null && !this.serverAsync.isCancelled()){
+            this.serverAsync.cancel(true);
+        }
+
+        if(this.clientAsync != null && !this.clientAsync.isCancelled()){
+            this.clientAsync.cancel(true);
+        }
+    }
+
     public void registerListeners(){
         mTxtP2PChangeDeviceName.setOnClickListener(new View.OnClickListener() {
             @Override
@@ -185,6 +200,16 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
         }
     }
 
+    private WifiP2pDevice getConnectedPeer(){
+        for(WifiP2pDevice device: peers){
+            if(device.status == WifiP2pDevice.CONNECTED){
+                return device;
+            }
+        }
+
+        return null;
+    }
+
     private static String getDeviceStatus(int deviceStatus) {
         switch (deviceStatus) {
             case WifiP2pDevice.AVAILABLE:
@@ -211,7 +236,7 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
 
     @Override
     public void onChannelDisconnected() {
-
+        closeConnection();
     }
 
     @Override
@@ -241,11 +266,20 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
         //if(mOtherDevice == null) return;
 
         if(info.groupFormed && info.isGroupOwner){
-            new FileServerAsyncTask(this, OWNER_SERVER_PORT).execute();
-            //new FileTransferAsyncTask(this, mOtherDevice.deviceAddress, CLIENT_SERVER_PORT).execute();
+            Log.i("server", "I am the group owner!");
+            WifiP2pDevice connectedPeer = getConnectedPeer();
+            if(connectedPeer != null && mInfo != null){
+                Log.i("peers", mInfo.groupFormed + " - " + mInfo.isGroupOwner);
+                Log.i("server", "Starting async server!");
+                serverAsync = new ServerAsyncTask(this, OWNER_SERVER_PORT);
+                serverAsync.execute();
+            }
+            //new ClientAsyncTask(this, mOtherDevice.deviceAddress, CLIENT_SERVER_PORT).execute();
         } else if(info.groupFormed){
-            //new FileServerAsyncTask(this, CLIENT_SERVER_PORT).execute();
-            new FileTransferAsyncTask(this, mInfo.groupOwnerAddress.getHostAddress(), OWNER_SERVER_PORT).execute();
+            //new ServerAsyncTask(this, CLIENT_SERVER_PORT).execute();
+            Log.i("client", "Starting async client!");
+            clientAsync = new ClientAsyncTask(this, mInfo.groupOwnerAddress.getHostAddress(), OWNER_SERVER_PORT);
+            clientAsync.execute();
         }
     }
 
@@ -253,6 +287,11 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
 
     }
 
+    @Override
+    public void onGroupInfoAvailable(WifiP2pGroup group) {
+
+    }
+
     /**
      * Array adapter for ListFragment that maintains WifiP2pDevice list.
      */
@@ -283,9 +322,6 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
                     top.setText(device.deviceName);
                 }
                 if (bottom != null) {
-                    if(device.status == WifiP2pDevice.CONNECTED){
-                        mOtherDevice = device;
-                    }
                     bottom.setText(getDeviceStatus(device.status));
                 }
             }
@@ -293,14 +329,14 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
         }
     }
 
-    public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
-        private Context context;
+    public static class ServerAsyncTask extends AsyncTask<Void, Void, String> {
+        private Activity context;
         private int port;
 
         /**
          * @param context
          */
-        public FileServerAsyncTask(Context context, int port) {
+        public ServerAsyncTask(Activity context, int port) {
             this.context = context;
             this.port = port;
         }
@@ -309,7 +345,11 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
             try {
                 ServerSocket serverSocket = new ServerSocket(this.port);
 
+                Log.i("server", "Waiting for clients!");
+
                 Socket client = serverSocket.accept();
+
+                Log.i("server", "Client connected!");
                 /*final File f = new File(Environment.getExternalStorageDirectory() + "/"
                         + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
                         + ".txt");
@@ -320,10 +360,13 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
                 InputStream inputstream = client.getInputStream();
                 readToToast(inputstream);
 
+                Log.i("server", "writing to client");
                 client.getOutputStream().write(("HELLO I HOPE THIS WILL REACH IT'S DESTINATION. I am server").getBytes());
 
                 //copyFile(inputstream, new FileOutputStream(f));
+                inputstream.close();
                 serverSocket.close();
+
                 return "";
             } catch (IOException e) {
                 return null;
@@ -332,34 +375,54 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
 
 
         public void readToToast(InputStream inputStream){
-            byte buf[] = new byte[1024];
-            StringBuffer bf = new StringBuffer();
+            final String received = inputStreamToString(inputStream, 2048);
 
-            int len;
-            try {
-                while ((len = inputStream.read(buf)) != -1) {
-                    bf.append(buf);
+            Log.i("server", "Received: " + received);
 
+            context.runOnUiThread(new Runnable() {
+                public void run() {
+                    Toast.makeText(context, "Received: " + received, Toast.LENGTH_LONG).show();
                 }
-                inputStream.close();
-            } catch (IOException e) {
-                return;
+            });
+        }
+
+        public static String inputStreamToString(final InputStream is, final int bufferSize)
+        {
+            final char[] buffer = new char[bufferSize];
+            final StringBuilder out = new StringBuilder();
+            try {
+                final Reader in = new InputStreamReader(is, "UTF-8");
+                try {
+                    for (;;) {
+                        int rsz = in.read(buffer, 0, buffer.length);
+                        if (rsz < 0)
+                            break;
+                        out.append(buffer, 0, rsz);
+                    }
+                } finally {
+                    in.close();
+                }
+            } catch (UnsupportedEncodingException ex) {
+                ex.printStackTrace();
+            } catch (IOException ex) {
+                ex.printStackTrace();
             }
 
-            Toast.makeText(context, "Received: " + bf.toString(), Toast.LENGTH_LONG).show();
+            return out.toString();
         }
     }
 
-    public static class FileTransferAsyncTask extends AsyncTask<Void, Void, Void> {
+    public static class ClientAsyncTask extends AsyncTask<Void, Void, Void> {
         private Context context;
         private int port;
         private String host;
-        private static final int SOCKET_TIMEOUT = 5000;
+        private static final int SOCKET_TIMEOUT = 10000;
+        private int tryNum = 0;
 
         /**
          * @param context
          */
-        public FileTransferAsyncTask(Context context, String host, int port) {
+        public ClientAsyncTask(Context context, String host, int port) {
             this.context = context;
             this.host = host;
             this.port = port;
@@ -368,16 +431,35 @@ public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerList
         @Override
         protected Void doInBackground(Void... params) {
             Socket socket = new Socket();
+            tryNum++;
 
             try {
+                Log.i("client", "trying to connect to " + host + ":" + port);
                 socket.bind(null);
                 socket.connect(new InetSocketAddress(host, port), SOCKET_TIMEOUT);
 
+                Log.i("client", "connected to server");
                 OutputStream stream = socket.getOutputStream();
 
+                Log.i("client", "sending: " + "HELLO I HOPE THIS WILL REACH IT'S DESTINATION. I am " + host);
                 stream.write(("HELLO I HOPE THIS WILL REACH IT'S DESTINATION. I am " + host).getBytes());
+                stream.flush();
+                stream.close();
+                socket.close();
             } catch (IOException e) {
-                e.printStackTrace();
+                if(tryNum >= 12) {
+                    return null;
+                }
+
+                long seconds_to_wait = (long) Math.min(60, Math.pow(2, tryNum));
+                Log.i("client", "could not connect to server. Will try again in " + seconds_to_wait + "s");
+
+                try {
+                    Thread.sleep(seconds_to_wait * 1000);
+                    doInBackground(params);
+                } catch (InterruptedException e1) {
+                    e1.printStackTrace();
+                }
             }
 
             return null;

+ 1 - 1
src/de/tudarmstadt/informatik/hostage/ui/fragment/RecordOverviewFragment.java

@@ -44,7 +44,7 @@ import de.tudarmstadt.informatik.hostage.logging.NetworkRecord;
 import de.tudarmstadt.informatik.hostage.logging.Record;
 import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
 import de.tudarmstadt.informatik.hostage.sync.bluetooth.BluetoothSyncActivity;
-import de.tudarmstadt.informatik.hostage.sync.nfc.NFCSync;
+import de.tudarmstadt.informatik.hostage.sync.nfc.NFCSyncActivity;
 import de.tudarmstadt.informatik.hostage.sync.p2p.P2PSyncActivity;
 import de.tudarmstadt.informatik.hostage.sync.tracing.TracingSyncActivity;
 import de.tudarmstadt.informatik.hostage.ui.activity.MainActivity;