diff --git a/.idea/modules.xml b/.idea/modules.xml
index 4c9d0f4..b36e3f6 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -3,10 +3,7 @@
-
-
-
\ No newline at end of file
diff --git a/app/src/androidTest/java/ch/ethz/inf/vs/fstreun/payapp/DataServiceTest.java b/app/src/androidTest/java/ch/ethz/inf/vs/fstreun/payapp/DataServiceTest.java
index e362d8c..40f5e8a 100644
--- a/app/src/androidTest/java/ch/ethz/inf/vs/fstreun/payapp/DataServiceTest.java
+++ b/app/src/androidTest/java/ch/ethz/inf/vs/fstreun/payapp/DataServiceTest.java
@@ -40,7 +40,7 @@ public class DataServiceTest {
@ClassRule
public static final ServiceTestRule mServiceRule = new ServiceTestRule();
- private static DataService.LocalBinder binder;
+ private static DataService.DataServiceBinder binder;
private static UUID userID;
@@ -61,7 +61,7 @@ public static void setBinder() throws TimeoutException {
DataService.class);
// Bind the service and grab a reference to the binder.
- binder = (DataService.LocalBinder) mServiceRule.bindService(serviceIntent);
+ binder = (DataService.DataServiceBinder) mServiceRule.bindService(serviceIntent);
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2448c70..f1544cd 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -45,18 +45,18 @@
android:parentActivityName=".MainActivity" />
-
-
+
+
expected = new HashMap<>();
+ JSONArray jsonMap = object.getJSONArray(NetworkKeys.LENGTHMAP);
+
+ for (int i = 0; i < jsonMap.length(); i++) {
+ JSONObject item = (JSONObject) jsonMap.get(i);
+ UUID mUUid = UUID.fromString( item.getString(NetworkKeys.DEVICEID));
+ Integer mLength = Integer.valueOf(item.getString(NetworkKeys.LENGHT));
+ expected.put(mUUid, mLength);
+ }
+
+ // save data
+ mSessionAccess.putData(data, expected);
+
+ } catch (JSONException e) {
+ // response body is not json
+ Log.e(TAG, "Response body handling failed, due to JSONException", e);
+ }
+
+
+ }
+
+
+ private String generateRequest(String host, int port, String body) {
+ String path = "/dataSync";
+ String accept = "text/plain";
+ String connect = "Closed";
+
+
+ return "GET " + path + " HTTP/1.1\r\n"
+ + "Host: " + host + ":" + port + "\r\n"
+ + "Accept: " + accept + "\r\n"
+ + "Connection: " + connect + "\r\n\r\n"
+ + body + "\r\n"
+ + "\r\n";
+ }
+
+
+ private String generateRequestBody() throws JSONException {
+
+ // get data for request (UUID sessionId, Map start)
+ UUID sessionId = mSessionAccess.getSessionID();
+ Map mData = mSessionAccess.getLength();
+
+ // create json request
+ JSONObject jsonRequest = new JSONObject();
+ jsonRequest.put(NetworkKeys.SESSIONID, sessionId.toString());
+ jsonRequest.put(NetworkKeys.COMMAND, "start");
+ JSONArray mJsonMap = new JSONArray();
+
+ for (Map.Entry item : mData.entrySet()) {
+ UUID deviceId = item.getKey();
+ Integer length = item.getValue();
+
+ JSONObject mJsonItem = new JSONObject();
+ mJsonItem.put(NetworkKeys.DEVICEID, deviceId.toString());
+ mJsonItem.put(NetworkKeys.LENGHT, length.toString());
+ mJsonMap.put(mJsonItem);
+ }
+
+ jsonRequest.put(NetworkKeys.LENGTHMAP, mJsonMap);
+
+ return jsonRequest.toString();
+ }
+}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSyncSubscribeService.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSync/Client/DataSyncSubscribeService.java
similarity index 56%
rename from app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSyncSubscribeService.java
rename to app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSync/Client/DataSyncSubscribeService.java
index 4f256b3..4d463e3 100644
--- a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSyncSubscribeService.java
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSync/Client/DataSyncSubscribeService.java
@@ -1,4 +1,4 @@
-package ch.ethz.inf.vs.fstreun.network;
+package ch.ethz.inf.vs.fstreun.network.DataSync.Client;
import android.app.Service;
import android.content.ComponentName;
@@ -11,28 +11,18 @@
import android.os.IBinder;
import android.util.Log;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.Map;
import java.util.Set;
import java.util.UUID;
import ch.ethz.inf.vs.fstreun.payapp.filemanager.DataService;
/**
- * Created by Kaan on 30.11.17.
+ * Created by fstreun on 25.12.17.
*
*/
@@ -48,7 +38,7 @@ public class DataSyncSubscribeService extends Service {
private Set mServiceInfos = new HashSet<>();
- DataService.LocalBinder dataServiceBinder;
+ DataService.DataServiceBinder dataServiceBinder;
boolean bound = false;
@Override
@@ -87,7 +77,7 @@ public void onDestroy() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (name.getClassName().equals(DataService.class.getName())){
- dataServiceBinder = (DataService.LocalBinder) service;
+ dataServiceBinder = (DataService.DataServiceBinder) service;
bound = true;
Log.d(TAG, "onServiceConnected: " + name.getClassName());
}
@@ -200,7 +190,7 @@ public void onServiceFound(NsdServiceInfo service) {
public void onServiceLost(NsdServiceInfo service) {
// When the network service is no longer available.
// Internal bookkeeping code goes here.
- Log.e(TAG, "service lost" + service);
+ Log.d(TAG, "service lost: " + service);
}
};
}
@@ -259,16 +249,20 @@ private class ClientThread implements Runnable {
public void run() {
- Log.i(TAG, "run()");
+ Log.d(TAG, "run()");
+
for (Iterator iterator = mServiceInfos.iterator(); iterator.hasNext();){
NsdServiceInfo serviceInfo = iterator.next();
InetAddress address = serviceInfo.getHost();
int port = serviceInfo.getPort();
- Socket socket = null;
try {
- socket = new Socket(address, port);
+ Socket socket = new Socket(address, port);
socket.setSoTimeout(1000);
- handleSocket(socket);
+
+ DataSyncSubscribe dataSyncSubscribe = new DataSyncSubscribe(mSessionAccess, socket);
+ // execute not concurrent
+ dataSyncSubscribe.run();
+
} catch (IOException e) {
Log.e(TAG, "new Socket Creation exception.", e);
iterator.remove();
@@ -278,162 +272,9 @@ public void run() {
// call that data is updated
mCallback.dataUpdated();
- Log.i(TAG, "run finished");
- }
-
- private void handleSocket(Socket socket){
- try {
-
- JSONObject requestBody = generateRequestBody();
-
- String get_message = generateRequest(socket.getInetAddress().toString(), socket.getPort(), "/dataSync", requestBody.toString());
-
- Log.d(TAG, "request: " + get_message);
-
- OutputStream mOutputStream = socket.getOutputStream();
-
- PrintWriter wtr = new PrintWriter(mOutputStream);
- wtr.print(get_message);
- //mOutputStream.write(get_message.getBytes());
- wtr.flush();
-
- BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
-
- String result = parseResponseForBody(input);
-
- Log.d(TAG, "response: " + result);
-
- JSONObject responseBody = new JSONObject(result);
-
- handleResponse(responseBody);
-
- socket.close();
- return;
- } catch (IOException e) {
- e.printStackTrace();
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
-
- private void handleResponse(JSONObject body){
- try {
- UUID sessionId = UUID.fromString(body.getString(NetworkKeys.SESSIONID));
- if (!sessionId.equals(mSessionAccess.getSessionID())){
- // data not supposed to be for this session
- return;
- }
- JSONObject data = body.getJSONObject(NetworkKeys.DATA);
-
- Map expected = new HashMap<>();
- JSONArray jsonMap = body.getJSONArray(NetworkKeys.LENGTHMAP);
-
- for (int i = 0; i < jsonMap.length(); i++) {
- JSONObject item = (JSONObject) jsonMap.get(i);
- UUID mUUid = UUID.fromString( item.getString(NetworkKeys.DEVICEID));
- Integer mLength = Integer.valueOf(item.getString(NetworkKeys.LENGHT));
- expected.put(mUUid, mLength);
- }
-
- // save data
- mSessionAccess.putData(data, expected);
- }catch (JSONException e){
- Log.e(TAG, "JSONException in handleResponse.", e);
- }
- }
-
- private JSONObject generateRequestBody() {
-
- JSONObject mJsonRequest = null;
-
- try {
- // get data for request (sessionId, Map start
- UUID sessionId = mSessionAccess.getSessionID();
- Map mData = mSessionAccess.getLength();
-
- // create json request
- mJsonRequest = new JSONObject();
- mJsonRequest.put(NetworkKeys.SESSIONID, sessionId.toString());
- mJsonRequest.put(NetworkKeys.COMMAND, "start");
- JSONArray mJsonMap = new JSONArray();
-
- for (Map.Entry item : mData.entrySet()) {
- UUID deviceId = item.getKey();
- Integer length = item.getValue();
-
- JSONObject mJsonItem = new JSONObject();
- mJsonItem.put(NetworkKeys.DEVICEID, deviceId.toString());
- mJsonItem.put(NetworkKeys.LENGHT, length.toString());
- mJsonMap.put(mJsonItem);
- }
- mJsonRequest.put(NetworkKeys.LENGTHMAP, mJsonMap);
- } catch (JSONException e) {
- Log.e(TAG, "JSONException in generateRequestBody.", e);
- }
-
- return mJsonRequest;
+ Log.d(TAG, "run finished");
}
- public String generateRequest(String host, int port, String path, String body) {
- String accept = "text/plain";
- String connect = "Closed";
-
-
- String request = "GET " + path + " HTTP/1.1\r\n"
- + "Host: " + host + ":" + port + "\r\n"
- + "Accept: " + accept + "\r\n"
- + "Connection: " + connect + "\r\n\r\n"
- + body + "\r\n"
- + "\r\n";
-
- return request;
- }
-
- private String parseResponseForBody(BufferedReader input) {
- // parse all header fields
-
- try {
- String statusLine = input.readLine();
- if (statusLine == null || statusLine.isEmpty()) {
- return "";
- }
-
- String lengthLine = input.readLine();
- if (lengthLine == null || lengthLine.isEmpty()) {
- return "";
- }
-
- String typeLine = input.readLine();
- if (typeLine == null || typeLine.isEmpty()) {
- return "";
- }
-
- String connectionLine = input.readLine();
- if (connectionLine == null || connectionLine.isEmpty()) {
- return "";
- }
-
- String emptyLine = input.readLine();
- if (emptyLine == null || !emptyLine.isEmpty()){
- return "";
- }
-
- StringBuilder result = new StringBuilder();
- String line;
-
- while ((line = input.readLine()) != null){
- if (line.isEmpty()){
- break;
- }else {
- result.append(line).append("\r\n");
- }
- }
- return result.toString();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return "";
- }
}
}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSync/Server/DataSyncPublish.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSync/Server/DataSyncPublish.java
new file mode 100644
index 0000000..0e36420
--- /dev/null
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSync/Server/DataSyncPublish.java
@@ -0,0 +1,159 @@
+package ch.ethz.inf.vs.fstreun.network.DataSync.Server;
+
+import android.util.Log;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import ch.ethz.inf.vs.fstreun.network.HttpParser;
+import ch.ethz.inf.vs.fstreun.network.NetworkKeys;
+import ch.ethz.inf.vs.fstreun.payapp.filemanager.DataService;
+
+/**
+ * Created by fabio on 12/25/17.
+ *
+ */
+
+public class DataSyncPublish implements Runnable{
+
+ private final String TAG = "DataSyncPublish";
+
+ private final DataService.DataServiceBinder mServiceBinder;
+ private final Socket mSocket;
+
+ DataSyncPublish(DataService.DataServiceBinder serviceBinder, Socket socket){
+ mServiceBinder = serviceBinder;
+ mSocket = socket;
+ }
+
+ @Override
+ public void run() {
+ try {
+ handleCommunication();
+ } catch (IOException e) {
+ Log.e(TAG, "handleCommunication throws IOException", e);
+ }
+
+ if (mSocket != null){
+ try {
+ mSocket.close();
+ Log.d(TAG, "closed socket");
+ } catch (IOException e) {
+ Log.e(TAG, "failed closing socket");
+ }
+ }
+ }
+
+ private void handleCommunication() throws IOException {
+
+ // get input buffer
+ BufferedReader input = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
+
+ // parser http request
+ HttpParser httpParser = new HttpParser(input);
+ Log.d(TAG, "request: " + httpParser);
+
+ if (httpParser.isError()){
+ // error occurred during http parsing.
+ Log.e(TAG, "HTTP Parsing error occurred");
+
+ input.close();
+ return;
+ }
+
+ // get http body
+ String bodyString = httpParser.getBody();
+
+ // get output buffer
+ BufferedWriter output = new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream()));
+ PrintWriter wtr = new PrintWriter(output);
+
+ // Create Here Response String
+ String responseBody = generateResponseBody(bodyString);
+
+ Log.d(TAG, "response: " + responseBody);
+
+ wtr.print(generateResponse(responseBody));
+ wtr.flush();
+ wtr.close();
+
+ input.close();
+ }
+
+ private String generateResponse(String body) {
+
+ return "HTTP/1.1 200 OK\r\n" +
+ "Content-Length: " + body.length() + "\r\n" +
+ "Content-Type: application/json\r\n" +
+ "Connection: Closed\r\n\r\n" + body+ "\r\n\r\n";
+ }
+
+ private String generateResponseBody(String requestBody) {
+
+ if (mServiceBinder == null) {
+ // service not available
+ return "{\"" + NetworkKeys.SUCCESS + "\": false}";
+ }
+
+ JSONObject json;
+ try {
+ json = new JSONObject(requestBody);
+
+ return generateResponseBody(json).toString();
+
+ } catch (JSONException e) {
+ // requestBody is not a JSON
+ return "{\"" + NetworkKeys.SUCCESS + "\": false}";
+ }
+
+ }
+
+ private JSONObject generateResponseBody(JSONObject requestBody) throws JSONException {
+ JSONObject jsonResponse = new JSONObject();
+
+ // get requested sessionID
+ UUID sessionID = UUID.fromString(requestBody.getString(NetworkKeys.SESSIONID));
+
+ // get access to session
+ DataService.SessionNetworkAccess sessionAccess = mServiceBinder.getSessionNetworkAccess(sessionID);
+ if (sessionAccess == null){
+ // no such session available
+ Log.d(TAG, "Session not available on this device.");
+ jsonResponse.put(NetworkKeys.SUCCESS, false);
+ return jsonResponse;
+ }
+
+ // get start map
+ JSONArray jsonMap = requestBody.getJSONArray(NetworkKeys.LENGTHMAP);
+ Map start = new HashMap<>(jsonMap.length());
+ for (int i = 0; i < jsonMap.length(); i++){
+ JSONObject jsonItem = jsonMap.getJSONObject(i);
+ UUID deviceID = UUID.fromString(jsonItem.getString(NetworkKeys.DEVICEID));
+ Integer length = Integer.valueOf(jsonItem.getString(NetworkKeys.LENGHT));
+ start.put(deviceID, length);
+ }
+
+ // get data after start
+ JSONObject data = sessionAccess.getData(start);
+
+ // put data.
+ jsonResponse.put(NetworkKeys.SESSIONID, sessionID.toString());
+ jsonResponse.put(NetworkKeys.LENGTHMAP, jsonMap);
+ jsonResponse.put(NetworkKeys.DATA, data);
+ jsonResponse.put(NetworkKeys.SUCCESS, true);
+
+ return jsonResponse;
+ }
+}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSync/Server/DataSyncPublishService.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSync/Server/DataSyncPublishService.java
new file mode 100644
index 0000000..83508b5
--- /dev/null
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSync/Server/DataSyncPublishService.java
@@ -0,0 +1,199 @@
+package ch.ethz.inf.vs.fstreun.network.DataSync.Server;
+
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+
+import ch.ethz.inf.vs.fstreun.payapp.filemanager.DataService;
+
+/**
+ * Created by fstreun on 25.12.17.
+ *
+ */
+
+public class DataSyncPublishService extends Service {
+
+ String TAG = "DataSyncPublishService";
+ String SERVICE_TYPE = "_http._tcp.";
+ String SERVICE_NAME = "DataSyncPublisher";
+ private NsdManager mNsdManager;
+ private NsdServiceInfo mServiceInfo;
+ private String mServiceName;
+ private ServerSocket mServerSocket = null;
+ private int mLocalPort;
+ private NsdManager.RegistrationListener mRegistrationListener;
+
+ DataService.DataServiceBinder dataServiceBinder;
+ boolean bound = false;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ // start server Socket
+ initializeServerSocket();
+ // Bind DataService
+ Intent intent = new Intent(this, DataService.class);
+ bindService(intent, connection, BIND_AUTO_CREATE);
+ }
+
+ public void initializeServerSocket() {
+ // Initialize a server socket on the next available port.
+ if (mServerSocket == null) {
+ try {
+ mServerSocket = new ServerSocket(0);
+ // start master network thread
+ new Thread(new ServerMasterThread()).start();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ // Store the chosen port.
+ mLocalPort = mServerSocket.getLocalPort();
+ }
+ }
+
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ // unregister service
+ if (mNsdManager != null) {
+ mNsdManager.unregisterService(mRegistrationListener);
+ }
+ mNsdManager = null;
+
+ // stop ServerSocket
+ if (mServerSocket != null){
+ try {
+ mServerSocket.close();
+ } catch (IOException e) {
+ Log.e(TAG, "failed to close ServerSocket");
+ }
+ }
+
+ // Unbind from service
+ if (bound){
+ unbindService(connection);
+ bound = false;
+ }
+ }
+
+ ServiceConnection connection = new ServiceConnection() {
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ if (name.getClassName().equals(DataService.class.getName())){
+ dataServiceBinder = (DataService.DataServiceBinder) service;
+ bound = true;
+ Log.d(TAG, "onServiceConnected: " + name.getClassName());
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.e(TAG, "onServiceDisconnected");
+ bound = false;
+ }
+ };
+
+
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ // TODO: Return the communication channel to the service.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ initializeRegistrationListener();
+ registerService(mLocalPort);
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+
+
+ public void registerService(int port) {
+ // Create the NsdServiceInfo object, and populate it.
+ mServiceInfo = new NsdServiceInfo();
+
+ // The name is subject to change based on conflicts
+ // with other services advertised on the same network.
+ mServiceInfo.setServiceName(SERVICE_NAME);
+ mServiceInfo.setServiceType(SERVICE_TYPE);
+ mServiceInfo.setPort(port);
+
+ mNsdManager = (NsdManager) this.getSystemService(Context.NSD_SERVICE);
+
+ mNsdManager.registerService(mServiceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
+ }
+
+
+ public void initializeRegistrationListener() {
+ mRegistrationListener = new NsdManager.RegistrationListener() {
+
+ @Override
+ public void onRegistrationFailed(NsdServiceInfo nsdServiceInfo, int errorCode) {
+ Log.d(TAG, "Registration Failed: " + errorCode);
+ }
+
+ @Override
+ public void onUnregistrationFailed(NsdServiceInfo nsdServiceInfo, int errorCode) {
+ Log.d(TAG, "Unregistration Failed: " + errorCode);
+ }
+
+ @Override
+ public void onServiceRegistered(NsdServiceInfo nsdServiceInfo) {
+ mServiceName = mServiceInfo.getServiceName();
+ Log.d(TAG, "onServiceRegistered: " + mServiceName);
+ }
+
+ @Override
+ public void onServiceUnregistered(NsdServiceInfo nsdServiceInfo) {
+ Log.d(TAG, "onServiceUnregistered: " + nsdServiceInfo.getServiceName());
+ }
+ };
+ }
+
+ class ServerMasterThread implements Runnable {
+
+ private final static String TAG = "ServerMasterThread";
+
+ public void run() {
+ Log.i("ServerMasterThread", "run()");
+ while (mServerSocket != null && !mServerSocket.isClosed()) {
+
+ try {
+ Log.i(TAG, "run() - open RequestThread");
+ Socket socket = mServerSocket.accept();
+ socket.setSoTimeout(1000);
+
+ // start slave thread
+ DataSyncPublish slaveThread = new DataSyncPublish(dataServiceBinder, socket);
+
+ // run not concurrent
+ slaveThread.run();
+
+
+ } catch (SocketException e) {
+ // socket closed
+ Log.e(TAG, "socket exception, probably closed.", e);
+ } catch (IOException e) {
+ Log.e(TAG, "io excepted.", e);
+ }
+ }
+ }
+ }
+
+}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSyncPublishService.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSyncPublishService.java
deleted file mode 100644
index 93f876c..0000000
--- a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/DataSyncPublishService.java
+++ /dev/null
@@ -1,373 +0,0 @@
-package ch.ethz.inf.vs.fstreun.network;
-
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.net.nsd.NsdManager;
-import android.net.nsd.NsdServiceInfo;
-import android.os.IBinder;
-import android.util.Log;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-import ch.ethz.inf.vs.fstreun.payapp.R;
-import ch.ethz.inf.vs.fstreun.payapp.filemanager.DataService;
-
-/**
- * Created by Kaan on 30.11.17.
- *
- */
-
-public class DataSyncPublishService extends Service {
-
- String TAG = "DataSyncPublishService";
- String SERVICE_TYPE = "_http._tcp.";
- String SERVICE_NAME = "DataSyncPublisher";
- private NsdManager mNsdManager;
- private NsdServiceInfo mServiceInfo;
- private String mServiceName;
- private ServerSocket mServerSocket = null;
- private int mLocalPort;
- private NsdManager.RegistrationListener mRegistrationListener;
-
- DataService.LocalBinder dataServiceBinder;
- boolean bound = false;
-
- private boolean registered;
-
- @Override
- public void onCreate() {
- super.onCreate();
- // start server Socket
- initializeServerSocket();
- // Bind DataService
- Intent intent = new Intent(this, DataService.class);
- bindService(intent, connection, BIND_AUTO_CREATE);
- }
-
- public void initializeServerSocket() {
- // Initialize a server socket on the next available port.
- if (mServerSocket == null) {
- try {
- mServerSocket = new ServerSocket(0);
- // start master network thread
- new Thread(new ServerMasterThread()).start();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- // Store the chosen port.
- mLocalPort = mServerSocket.getLocalPort();
- }
- }
-
-
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- // Unbind from service
- if (bound){
- unbindService(connection);
- bound = false;
- }
-
- // unregister service
- if (mNsdManager != null) {
- mNsdManager.unregisterService(mRegistrationListener);
- }
- //registered = false;
- mNsdManager = null;
-
- // stop ServerSocket
- if (mServerSocket != null){
- try {
- mServerSocket.close();
- } catch (IOException e) {
- Log.e(TAG, "failed to close ServerSocket");
- }
- }
-
-
- }
-
- ServiceConnection connection = new ServiceConnection() {
-
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- if (name.getClassName().equals(DataService.class.getName())){
- dataServiceBinder = (DataService.LocalBinder) service;
- bound = true;
- Log.d(TAG, "onServiceConnected: " + name.getClassName());
- }
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- Log.e(TAG, "onServiceDisconnected");
- bound = false;
- }
- };
-
-
-
- @Override
- public IBinder onBind(Intent intent) {
- // TODO: Return the communication channel to the service.
- throw new UnsupportedOperationException("Not yet implemented");
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- Log.d(TAG, "onStartCommand. registered: " + registered);
- //if (!registered) {
- initializeRegistrationListener();
- registerService(mLocalPort);
- //}
- return super.onStartCommand(intent, flags, startId);
- }
-
-
-
- public void registerService(int port) {
- // Create the NsdServiceInfo object, and populate it.
- mServiceInfo = new NsdServiceInfo();
-
- // The name is subject to change based on conflicts
- // with other services advertised on the same network.
- mServiceInfo.setServiceName(SERVICE_NAME);
- mServiceInfo.setServiceType(SERVICE_TYPE);
- mServiceInfo.setPort(port);
-
- mNsdManager = (NsdManager) this.getSystemService(Context.NSD_SERVICE);
-
- mNsdManager.registerService(mServiceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
-
- registered = true;
- }
-
-
- public void initializeRegistrationListener() {
- mRegistrationListener = new NsdManager.RegistrationListener() {
-
- @Override
- public void onRegistrationFailed(NsdServiceInfo nsdServiceInfo, int errorCode) {
- Log.d(TAG, "Registration Failed: " + errorCode);
- }
-
- @Override
- public void onUnregistrationFailed(NsdServiceInfo nsdServiceInfo, int errorCode) {
- Log.d(TAG, "Unregistration Failed: " + errorCode);
- }
-
- @Override
- public void onServiceRegistered(NsdServiceInfo nsdServiceInfo) {
- mServiceName = mServiceInfo.getServiceName();
- Log.d(TAG, "onServiceRegistered: " + mServiceName);
- }
-
- @Override
- public void onServiceUnregistered(NsdServiceInfo nsdServiceInfo) {
- Log.d(TAG, "onServiceUnregistered: " + nsdServiceInfo.getServiceName());
- }
- };
- }
-
- class ServerMasterThread implements Runnable {
-
- private final static String TAG = "ServerMasterThread";
-
- public void run() {
- Log.i("ServerMasterThread", "run()");
- while (mServerSocket != null && !mServerSocket.isClosed()) {
-
- try {
- Log.i(TAG, "run() - open RequestThread");
- Socket socket = mServerSocket.accept();
- socket.setSoTimeout(1000);
- // start slave thread
- ServerSlaveThread slaveThread = new ServerSlaveThread(socket);
- slaveThread.run();
-
-
- } catch (SocketException e) {
- // socket closed
- Log.e(TAG, "socket exception, probably closed.", e);
- } catch (IOException e) {
- Log.e(TAG, "io excepted.", e);
- }
- }
- }
- }
-
- class ServerSlaveThread implements Runnable{
-
- private final static String TAG = "ServerSlaveThread";
-
- private final Socket mSocket;
-
- ServerSlaveThread(Socket socket) {
- this.mSocket = socket;
- }
-
- @Override
- public void run() {
-
- try {
- Log.d(TAG, "run");
- if (!bound){
- // session access service not available
- mSocket.close();
- return;
- }
-
- BufferedReader input = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
-
- String jsonBodyString = parseRequestForBody(input);
-
- Log.d(TAG, "request: " + jsonBodyString);
-
- JSONObject jsonBody = new JSONObject(jsonBodyString);
-
-
- BufferedWriter output = new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream()));
-
- PrintWriter wtr = new PrintWriter(output);
-
- // Create Here Response String (favourably JSON)
- JSONObject responseBody = generateResponseBody(jsonBody);
- String stringBody = "";
- if (responseBody != null){
- stringBody = responseBody.toString();
- }
- Log.d(TAG, "response: " + stringBody);
-
- wtr.print(generateResponse(stringBody));
- wtr.flush();
- wtr.close();
-
- Log.d(TAG, "run finished without exception");
- }catch (IOException e){
- e.printStackTrace();
- }catch (JSONException e){
- e.printStackTrace();
- }
- }
-
- private String generateResponse(String body) {
- String response = "HTTP/1.1 200 OK\r\n" +
- "Content-Length: " + body.length() + "\r\n" +
- "Content-Type: application/json\r\n" +
- "Connection: Closed\r\n\r\n" + body+ "\r\n\r\n";
- return response;
- }
-
- private JSONObject generateResponseBody(JSONObject requestBody){
- JSONObject jsonResponse = null;
- try {
- UUID sessionID = UUID.fromString(requestBody.getString(NetworkKeys.SESSIONID));
-
- DataService.SessionNetworkAccess sessionAccess = dataServiceBinder.getSessionNetworkAccess(sessionID);
- if (sessionAccess == null){
- // no such session available
- Log.d(TAG, "Session not available on this device.");
- return null;
- }
-
- String command = requestBody.getString(NetworkKeys.COMMAND);
-
-
- JSONArray jsonMap = requestBody.getJSONArray(NetworkKeys.LENGTHMAP);
-
- Map start = new HashMap<>(jsonMap.length());
-
- for (int i = 0; i < jsonMap.length(); i++){
- JSONObject jsonItem = jsonMap.getJSONObject(i);
- UUID deviceID = UUID.fromString(jsonItem.getString(NetworkKeys.DEVICEID));
- Integer length = Integer.valueOf(jsonItem.getString(NetworkKeys.LENGHT));
- start.put(deviceID, length);
- }
-
- JSONObject data = sessionAccess.getData(start);
-
- jsonResponse = new JSONObject();
- jsonResponse.put(NetworkKeys.SESSIONID, sessionID.toString());
- jsonResponse.put(NetworkKeys.LENGTHMAP, jsonMap);
- jsonResponse.put(NetworkKeys.DATA, data);
-
- }catch (JSONException e){
- Log.e(TAG, "JSONException in generateResponseBody.", e);
- return null;
- }
- return jsonResponse;
- }
-
- private String parseRequestForBody(BufferedReader input) {
- // parse all header fields
-
- try {
- String requestLine = input.readLine();
-
- if (requestLine == null || requestLine.isEmpty()) {
- return "";
- }
-
- String hostLine = input.readLine();
- if (hostLine == null || hostLine.isEmpty()) {
- return "";
- }
-
- String acceptLine = input.readLine();
- if (acceptLine == null || acceptLine.isEmpty()) {
- return "";
- }
-
- String connectionLine = input.readLine();
- if (connectionLine == null || connectionLine.isEmpty()) {
- return "";
- }
-
- String emptyLine = input.readLine();
- if (emptyLine == null || !emptyLine.isEmpty()){
- return "";
- }
-
- StringBuilder result = new StringBuilder();
- String line;
-
- while ((line = input.readLine()) != null){
- if (line.isEmpty()){
- Log.d(TAG, result.toString());
- break;
- }else {
- result.append(line).append("\r\n");
- }
- }
- return result.toString();
- } catch (IOException e) {
- Log.e(TAG, "IOException in parseRequestForBody");
- }
- return "";
- }
-
-
- }
-}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/HttpParser.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/HttpParser.java
new file mode 100644
index 0000000..4c085d7
--- /dev/null
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/HttpParser.java
@@ -0,0 +1,255 @@
+package ch.ethz.inf.vs.fstreun.network;
+
+import android.support.annotation.NonNull;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by fabio on 12/23/17.
+ * Parses HTTP requests.
+ * Body is only read if Content-Length is available
+ */
+
+public class HttpParser {
+
+ private final String TAG = "HTTPPARSER";
+
+ // BufferedReader given in the constructor and used by the parser.
+ public final BufferedReader bufferedReader;
+
+ private String requestLine;
+ private String requestMethod;
+ private String requestURI;
+ private String requestHTTPVersion;
+
+ private String head = "";
+ private Map headerFields = new HashMap<>();
+
+ private String body = "";
+
+ private boolean error;
+ private List exceptions = new ArrayList<>();
+
+ public HttpParser(@NonNull BufferedReader bufferedReader){
+
+ this.bufferedReader = bufferedReader;
+
+ try {
+
+ // parse first line
+ String firstLine = bufferedReader.readLine();
+ if (firstLine == null || firstLine.isEmpty()){
+ error = true;
+ exceptions.add(new IOException("HTTP Parser Error: could not read from buffered reader!"));
+ return;
+ }
+
+ try {
+ // might throw IOException if format is wrong
+ parserRequestLine(firstLine);
+ }catch (IOException e){
+ // wrong format of request line.
+ error = true;
+ exceptions.add(new IOException("HTTP Parser Error: wrong request line format.", e));
+ }
+
+
+ // parse all header fields
+ String headerLine;
+ while ((headerLine = bufferedReader.readLine()) != null){
+ if (headerLine.isEmpty()){
+ // end of header
+ break;
+ }else {
+ try {
+
+ // might throw IOException if format is wrong
+ parseHeaderFields(headerLine);
+ }catch (IOException e){
+ error = true;
+ exceptions.add(new IOException("HTTP Parser Error: wrong header line format.", e));
+ }
+ }
+ }
+
+
+ // get content length header field.
+ String contentLength = getHeaderFieldValue("Content-Length");
+ Integer maxLength = null;
+
+ if (contentLength != null){
+ // header field is available
+ try{
+ maxLength = Integer.parseInt(contentLength);
+ }catch (NumberFormatException e){
+ // unsuccessful parsing of integer
+ error = true;
+ exceptions.add(new IOException("HTTP Parser Error: Failed to parser Content-Length header value: " + contentLength, e));
+ }
+ }
+
+
+ if (maxLength != null) {
+ // read body char by char
+ StringBuilder bodyLine = new StringBuilder(maxLength);
+ int c;
+ for (int i = 0; i < maxLength; i++) {
+ c = bufferedReader.read();
+ bodyLine.append((char) c);
+ }
+
+ parseBody(bodyLine.toString());
+ }
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ error = true;
+ exceptions.add(new IOException("Http Parser Error", e));
+ }
+ }
+
+
+ /**
+ * Parses the request line of a http request
+ * @param line has to contain at most three parameters split by a space
+ * @throws IOException if to many many parameters are there
+ */
+ private void parserRequestLine(@NonNull String line) throws IOException {
+ String[] parts = line.split(" ", -1);
+
+ requestLine = line;
+
+ if (parts.length < 3){
+ throw new IOException("Illegal request line format: " + line);
+ }
+
+ // TODO: distinguish between response and request...
+
+ if (parts[0].startsWith("HTTP")){
+ // it is a response
+
+ }else{
+ // it is a request
+ if (parts.length != 3){
+ throw new IOException("Illegal request line format: " + line);
+ }
+
+ requestMethod = parts[0];
+ requestURI = parts[1];
+ requestHTTPVersion = parts[2];
+ }
+
+ }
+
+ /**
+ * Parses header fields of a http request.
+ * Appends line to the string head.
+ * Case-insensitive and appends values of the same header field with a comma to each other.
+ * @param line contains a header key ending with a ':' and followed by values.
+ * @throws IOException if format is not fulfilled
+ */
+ private void parseHeaderFields(@NonNull String line) throws IOException {
+
+ // check header line format
+ int endOfKey = line.indexOf(':');
+ if (endOfKey < 0){
+ throw new IOException("Following character is missing: ':' in the line: " + line);
+ }
+
+ // append line to head string
+ head += line + "\n";
+
+ // add line to header map
+ String fieldKey = line.substring(0, endOfKey);
+ String fieldValue = line.substring(endOfKey + 2);
+ if (headerFields.containsKey(fieldKey)){
+ // field key already parsed. Append new values with an comma.
+ fieldValue = headerFields.get(fieldKey) + ", " + fieldValue;
+ }
+ headerFields.put(fieldKey.toLowerCase(), fieldValue.toLowerCase());
+ }
+
+ /**
+ * parses the body of a http request.
+ * @param line to be append to the already parsed body
+ */
+ private void parseBody(@NonNull String line){
+ body += line;
+ }
+
+
+ /**
+ *
+ * @return the parsed requestLine
+ */
+ public String getRequestLine(){
+ return requestLine;
+ }
+
+ /**
+ *
+ * @return the parsed request method.
+ */
+ public String getRequestMethod() {
+ return requestMethod;
+ }
+
+ /**
+ *
+ * @return the parsed request URI
+ */
+ public String getRequestURI() {
+ return requestURI;
+ }
+
+ /**
+ *
+ * @return the parsed request HTTP Version
+ */
+ public String getRequestHTTPVersion() {
+ return requestHTTPVersion;
+ }
+
+ /**
+ *
+ * @param fieldKey (case-insensitive)
+ * @return header field value or null if not parsed
+ */
+ public String getHeaderFieldValue(String fieldKey){
+ return headerFields.get(fieldKey.toLowerCase());
+ }
+
+ /**
+ *
+ * @return the parsed body of the http request
+ */
+ public String getBody(){
+ return body;
+ }
+
+ /**
+ *
+ * @return true if an error occurred during parsing.
+ */
+ public boolean isError() {return error;}
+
+ /**
+ *
+ * @return a copy of the exception list.
+ */
+ public List getExceptions() {
+ return new ArrayList<>(exceptions);
+ }
+
+
+ @Override
+ public String toString() {
+ return error ? "Error occurred during http parsing" :
+ requestLine + "\n" + head + "\n" + body;
+ }
+}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/NetworkKeys.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/NetworkKeys.java
index 849f720..e1e6d86 100644
--- a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/NetworkKeys.java
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/NetworkKeys.java
@@ -4,15 +4,20 @@
* Created by fabio on 12/12/17.
*/
-final class NetworkKeys {
- static final String SESSIONID = "sessionID";
+public final class NetworkKeys {
+ public static final String SUCCESS = "success";
- static final String LENGTHMAP = "lengthmap";
- static final String DEVICEID = "deviceID";
- static final String LENGHT = "length";
+ public static final String SECRET = "secret";
+ public static final String GROUP = "group";
- static final String DATA = "data";
+ public static final String SESSIONID = "sessionID";
- static final String COMMAND = "command";
+ public static final String LENGTHMAP = "lengthmap";
+ public static final String DEVICEID = "deviceID";
+ public static final String LENGHT = "length";
+
+ public static final String DATA = "data";
+
+ public static final String COMMAND = "command";
}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublish/Client/GroupSubscribe.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublish/Client/GroupSubscribe.java
new file mode 100644
index 0000000..0b1369a
--- /dev/null
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublish/Client/GroupSubscribe.java
@@ -0,0 +1,152 @@
+package ch.ethz.inf.vs.fstreun.network.SessionPublish.Client;
+
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.Socket;
+
+import ch.ethz.inf.vs.fstreun.network.HttpParser;
+import ch.ethz.inf.vs.fstreun.network.NetworkKeys;
+
+/**
+ * Created by fabio on 12/25/17.
+ *
+ */
+
+public class GroupSubscribe implements Runnable{
+
+ private final String TAG = "GroupSubscribe";
+
+ private final Callback mCallback;
+ private final Socket mSocket;
+
+ GroupSubscribe(Callback callback, Socket socket){
+ mCallback = callback;
+ mSocket = socket;
+ }
+
+ @Override
+ public void run() {
+ try {
+ if (mCallback != null) {
+ handleCommunication();
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "handleCommunication throws IOException", e);
+ }
+
+ if (mSocket != null){
+ try {
+ mSocket.close();
+ Log.d(TAG, "closed socket");
+ } catch (IOException e) {
+ Log.e(TAG, "failed closing socket");
+ }
+ }
+ }
+
+ private void handleCommunication() throws IOException {
+
+ String requestBody;
+ try {
+ requestBody = generateRequestBody();
+ } catch (JSONException e) {
+ // generation of Request failed
+ Log.e(TAG, "Request generation failed!");
+ return;
+ }
+
+ String request = generateRequest(mSocket.getInetAddress().toString(), mSocket.getPort(), requestBody);
+ Log.d(TAG, "Request: " + request);
+
+ // get output stream and print writer
+ OutputStream outputStream = mSocket.getOutputStream();
+ PrintWriter printWriter = new PrintWriter(outputStream);
+
+ printWriter.print(request);
+ printWriter.flush();
+
+ // get input buffer
+ BufferedReader input = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
+
+ // parse http response
+ HttpParser httpParser = new HttpParser(input);
+ Log.d(TAG, "request: " + httpParser);
+
+ if (httpParser.isError()){
+ // error occurred druing http parsing.
+ Log.e(TAG, "HTTP Parsing error occurred");
+
+ input.close();
+ printWriter.close();
+ return;
+ }
+
+ // get http body
+ String bodyString = httpParser.getBody();
+
+ handleResponse(bodyString);
+
+ // clean up streams and buffers
+ input.close();
+ printWriter.close();
+
+ }
+
+ private void handleResponse(String responseBody) {
+
+ try {
+ JSONObject object = new JSONObject(responseBody);
+
+ Boolean success = object.getBoolean(NetworkKeys.SUCCESS);
+ if (!success){
+ // not successfull or wrong format
+ return;
+ }
+
+ String secret = object.getString(NetworkKeys.SECRET);
+ String group = object.getString(NetworkKeys.GROUP);
+
+ mCallback.groupFound(group, secret);
+
+ } catch (JSONException e) {
+ // response body is not json
+ Log.e(TAG, "Response body handling failed, due to JSONException", e);
+ }
+ }
+
+ private String generateRequest(String host, int port, String body) {
+ String path = "/joinGroup";
+ String accept = "text/plain";
+ String connect = "Closed";
+
+
+ return "GET " + path + " HTTP/1.1\r\n"
+ + "Host: " + host + ":" + port + "\r\n"
+ + "Accept: " + accept + "\r\n"
+ + "Connection: " + connect + "\r\n\r\n"
+ + body + "\r\n"
+ + "\r\n";
+ }
+
+
+ private String generateRequestBody() throws JSONException {
+
+ JSONObject jsonRequest = new JSONObject();
+ jsonRequest.put(NetworkKeys.SECRET, mCallback.getSecret());
+
+ return jsonRequest.toString();
+ }
+
+ public interface Callback{
+ String getSecret();
+ void groupFound(String simpleGroup, String secret);
+ }
+}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublish/Client/GroupSubscribeService.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublish/Client/GroupSubscribeService.java
new file mode 100644
index 0000000..14d724f
--- /dev/null
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublish/Client/GroupSubscribeService.java
@@ -0,0 +1,151 @@
+package ch.ethz.inf.vs.fstreun.network.SessionPublish.Client;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.io.IOException;
+import java.net.Socket;
+
+import ch.ethz.inf.vs.fstreun.payapp.JoinGroupActivity;
+
+public class GroupSubscribeService extends Service {
+
+ String TAG = "## GroupSubscribeService";
+ String SERVICE_TYPE = "_http._tcp.";
+ String SERVICE_NAME = "SessionSubscriber";
+
+ private NsdManager mNsdManager;
+ private NsdServiceInfo mService;
+ private NsdManager.DiscoveryListener mDiscoveryListener;
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ // TODO: Return the communication channel to the service.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ // initialize listener
+ initializeDiscoveryListener();
+ mNsdManager = (NsdManager) this.getSystemService(Context.NSD_SERVICE);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ mNsdManager.stopServiceDiscovery(mDiscoveryListener);
+
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+
+ if (mNsdManager == null){
+ Log.e(TAG, "FATAL ERRO: NSD Manager has not been properly initialized.");
+ stopSelf();
+ return START_STICKY;
+ }
+
+ mNsdManager.discoverServices(
+ SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
+
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+
+ public void initializeDiscoveryListener() {
+ // Instantiate a new DiscoveryListener
+ mDiscoveryListener = new NsdManager.DiscoveryListener() {
+
+ @Override
+ public void onStartDiscoveryFailed(String s, int errorCode ) {
+ Log.e(TAG, "Discovery failed: Error code:" + errorCode);
+ mNsdManager.stopServiceDiscovery(mDiscoveryListener);
+ }
+
+ @Override
+ public void onStopDiscoveryFailed(String s, int errorCode) {
+ Log.e(TAG, "Discovery failed: Error code:" + errorCode);
+ mNsdManager.stopServiceDiscovery(mDiscoveryListener);
+ }
+
+ @Override
+ public void onDiscoveryStarted(String s) {
+ Log.d(TAG, "Service discovery started: " + s);
+ }
+
+ @Override
+ public void onDiscoveryStopped(String serviceType) {
+ Log.i(TAG, "Discovery stopped: " + serviceType);
+ }
+
+ @Override
+ public void onServiceLost(NsdServiceInfo service) {
+ // When the network service is no longer available.
+ // Internal bookkeeping code goes here.
+ Log.e(TAG, "service lost" + service);
+ }
+
+ @Override
+ public void onServiceFound(NsdServiceInfo service) {
+ // A service was found! Do something with it.
+
+ Log.d(TAG, "onServiceFound: " + service);
+
+ if (!service.getServiceType().equals(SERVICE_TYPE)) {
+ // Service type is the string containing the protocol and
+ // transport layer for this service.
+ Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
+ } else if (service.getServiceName().equals(SERVICE_NAME)) {
+ // The name of the service tells the user what they'd be
+ // connecting to. It could be "Bob's Chat App".
+ Log.d(TAG, "Same machine: " + SERVICE_NAME);
+ } else if (service.getServiceName().contains("SessionPublisher")){
+ Log.d(TAG, "Resolve service: ");
+ mNsdManager.resolveService(service, new MyResolveListener());
+ }
+ }
+ };
+ }
+
+ class MyResolveListener implements NsdManager.ResolveListener {
+
+
+ @Override
+ public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int errorCode) {
+ // Called when the resolve fails. Use the error code to debug.
+ Log.w(TAG, "Resolve failed" + errorCode);
+ }
+
+ @Override
+ public void onServiceResolved(NsdServiceInfo serviceInfo) {
+ Log.w(TAG, "Resolve Succeeded. " + serviceInfo);
+
+ if (serviceInfo.getServiceName().equals(SERVICE_NAME)) {
+ Log.i(TAG, "Same IP.");
+ return;
+ }
+ mService = serviceInfo;
+ Socket socket = null;
+ try {
+ socket = new Socket(mService.getHost(), mService.getPort());
+ } catch (IOException e) {
+ Log.e(TAG, "onServiceResolved failed due to socket creation failure.", e);
+ return;
+ }
+
+ GroupSubscribe groupSubscribe = new GroupSubscribe(JoinGroupActivity.instance, socket);
+ new Thread(groupSubscribe).start();
+ }
+ }
+
+}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublish/Server/GroupPublish.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublish/Server/GroupPublish.java
new file mode 100644
index 0000000..de1691f
--- /dev/null
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublish/Server/GroupPublish.java
@@ -0,0 +1,131 @@
+package ch.ethz.inf.vs.fstreun.network.SessionPublish.Server;
+
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.util.Map;
+
+import ch.ethz.inf.vs.fstreun.network.HttpParser;
+import ch.ethz.inf.vs.fstreun.network.NetworkKeys;
+
+/**
+ * Created by fabio on 12/25/17.
+ *
+ */
+
+public class GroupPublish implements Runnable {
+
+ private final String TAG = "GroupPublish";
+
+ private final Map mGroups;
+ private final Socket mSocket;
+
+ GroupPublish(Map groups, Socket socket){
+ mGroups = groups;
+ mSocket = socket;
+ }
+
+ @Override
+ public void run() {
+ try {
+ handleCommunication();
+ } catch (IOException e) {
+ Log.e(TAG, "handleCommunication throws IOException", e);
+ }
+
+ if (mSocket != null){
+ try {
+ mSocket.close();
+ Log.d(TAG, "closed socket");
+ } catch (IOException e) {
+ Log.e(TAG, "failed closing socket");
+ }
+ }
+ }
+
+ private void handleCommunication() throws IOException {
+
+ // get input buffer
+ BufferedReader input = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
+
+ // parser http request
+ HttpParser httpParser = new HttpParser(input);
+ Log.d(TAG, "request: " + httpParser);
+
+ if (httpParser.isError()){
+ // error occurred during http parsing.
+ Log.e(TAG, "HTTP Parsing error occurred");
+
+ input.close();
+ return;
+ }
+
+ // get http body
+ String bodyString = httpParser.getBody();
+
+ // get output buffer
+ BufferedWriter output = new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream()));
+ PrintWriter wtr = new PrintWriter(output);
+
+ // Create Here Response String
+ String responseBody = generateResponseBody(bodyString);
+
+ Log.d(TAG, "response: " + responseBody);
+
+ wtr.print(generateResponse(responseBody));
+ wtr.flush();
+ wtr.close();
+
+ input.close();
+ }
+
+ private String generateResponse(String body) {
+
+ return "HTTP/1.1 200 OK\r\n" +
+ "Content-Length: " + body.length() + "\r\n" +
+ "Content-Type: application/json\r\n" +
+ "Connection: Closed\r\n\r\n" + body+ "\r\n\r\n";
+ }
+
+ private String generateResponseBody(String requestBody) {
+
+ try {
+ JSONObject json = new JSONObject(requestBody);
+
+ return generateResponseBody(json).toString();
+
+ } catch (JSONException e) {
+ // requestBody is not a JSON
+ return "{\"" + NetworkKeys.SUCCESS + "\": false}";
+ }
+
+ }
+
+ private JSONObject generateResponseBody(JSONObject requestBody) throws JSONException {
+ JSONObject jsonResponse = new JSONObject();
+
+ String secret = requestBody.getString(NetworkKeys.SECRET);
+
+ String groupString = mGroups.get(secret);
+
+ if (groupString != null){
+ jsonResponse.put(NetworkKeys.GROUP, groupString);
+ jsonResponse.put(NetworkKeys.SECRET, secret);
+ jsonResponse.put(NetworkKeys.SUCCESS, true);
+ }else {
+ jsonResponse.put(NetworkKeys.SUCCESS, false);
+ }
+ return jsonResponse;
+ }
+
+
+}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublishService.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublish/Server/GroupPublishService.java
similarity index 57%
rename from app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublishService.java
rename to app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublish/Server/GroupPublishService.java
index 7aaed56..eb45e1a 100644
--- a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublishService.java
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionPublish/Server/GroupPublishService.java
@@ -1,34 +1,24 @@
-package ch.ethz.inf.vs.fstreun.network;
+package ch.ethz.inf.vs.fstreun.network.SessionPublish.Server;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
-import java.net.SocketException;
-
-import ch.ethz.inf.vs.fstreun.payapp.R;
+import java.util.HashMap;
+import java.util.Map;
-public class SessionPublishService extends Service {
+public class GroupPublishService extends Service {
- String TAG = "## SessionPublishService";
+ String TAG = "## GroupPublishService";
String SERVICE_TYPE = "_http._tcp.";
String SERVICE_NAME = "SessionPublisher";
@@ -45,7 +35,7 @@ public class SessionPublishService extends Service {
private String secret;
private String groupJsonString;
- public SessionPublishService() {}
+ public GroupPublishService() {}
@Override
public IBinder onBind(Intent intent) {
@@ -58,16 +48,16 @@ public IBinder onBind(Intent intent) {
public class LocalBinder extends Binder {
public void setSecretGroup(String secret, String groupJSON){
- SessionPublishService.this.secret = secret;
- SessionPublishService.this.groupJsonString = groupJSON;
+ GroupPublishService.this.secret = secret;
+ GroupPublishService.this.groupJsonString = groupJSON;
Log.d(TAG, "setSecretGroup: " + secret + "\n" + groupJSON);
}
}
@Override
public boolean onUnbind(Intent intent) {
- SessionPublishService.this.secret = "";
- SessionPublishService.this.groupJsonString = "";
+ GroupPublishService.this.secret = "";
+ GroupPublishService.this.groupJsonString = "";
return super.onUnbind(intent);
}
@@ -208,8 +198,11 @@ public void run() {
Log.i(TAG, "ServerMainThread accepted socket");
socket.setSoTimeout(1000);
- ServerSlaveThread slaveThread = new ServerSlaveThread(socket);
+ Map groups = new HashMap<>(1);
+ groups.put(secret, groupJsonString);
+ GroupPublish slaveThread = new GroupPublish(groups, socket);
new Thread(slaveThread).start();
+
} catch (IOException e) {
Log.d(TAG, "ServerMainThread exception occured", e);
}
@@ -217,106 +210,4 @@ public void run() {
}
}
- class ServerSlaveThread implements Runnable {
-
- private final Socket socket;
-
- ServerSlaveThread(Socket socket){
- this.socket = socket;
- }
-
- @Override
- public void run() {
-
- try {
-
- BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
-
- String jsonBodyString = parseRequestForBody(input);
-
- JSONObject mJson = null;
- String key = "";
- mJson = new JSONObject(jsonBodyString);
- key = mJson.getString("secret");
-
- JSONObject response = new JSONObject();
- if (key.equals(secret)) {
- response.put("result", true);
- response.put("group", groupJsonString);
- } else {
- response.put("result", false);
- }
-
- BufferedWriter output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
-
- PrintWriter wtr = new PrintWriter(output);
- wtr.print(generateResponse(response.toString()));
- wtr.flush();
- wtr.close();
-
- } catch (SocketException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
-
- private String generateResponse(String body) {
- String response = "HTTP/1.1 200 OK\r\n" +
- "Content-Length: " + body.length() + "\r\n" +
- "Content-Type: application/json\r\n" +
- "Connection: Closed\r\n\r\n" + body + "\r\n\r\n";
- return response;
- }
-
- private String parseRequestForBody(BufferedReader input) {
- // parse all header fields
-
- try {
- String requestLine = input.readLine();
-
- if (requestLine == null || requestLine.isEmpty()) {
- return "";
- }
-
- String hostLine = input.readLine();
- if (hostLine == null || hostLine.isEmpty()) {
- return "";
- }
-
- String acceptLine = input.readLine();
- if (acceptLine == null || acceptLine.isEmpty()) {
- return "";
- }
-
- String connectionLine = input.readLine();
- if (connectionLine == null || connectionLine.isEmpty()) {
- return "";
- }
-
- String emptyLine = input.readLine();
- if (emptyLine == null || !emptyLine.isEmpty()){
- return "";
- }
-
- StringBuilder result = new StringBuilder();
- String line;
-
- while ((line = input.readLine()) != null){
- if (line.isEmpty()){
- Log.w(TAG, result.toString());
- break;
- }else {
- result.append(line).append("\r\n");
- }
- }
- return result.toString();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return "";
- }
- }
}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionSubscribeService.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionSubscribeService.java
deleted file mode 100644
index 0333d50..0000000
--- a/app/src/main/java/ch/ethz/inf/vs/fstreun/network/SessionSubscribeService.java
+++ /dev/null
@@ -1,308 +0,0 @@
-package ch.ethz.inf.vs.fstreun.network;
-
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.net.nsd.NsdManager;
-import android.net.nsd.NsdServiceInfo;
-import android.os.AsyncTask;
-import android.os.IBinder;
-import android.util.Log;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.net.Socket;
-
-import ch.ethz.inf.vs.fstreun.payapp.JoinGroupActivity;
-
-public class SessionSubscribeService extends Service {
-
- String TAG = "## SessionSubscribeService";
- String SERVICE_TYPE = "_http._tcp.";
- String SERVICE_NAME = "SessionSubscriber";
-
- private NsdManager mNsdManager;
- private NsdServiceInfo mService;
- private NsdManager.DiscoveryListener mDiscoveryListener;
-
- private String secret;
-
- private JoinGroupActivity activity;
-
- public SessionSubscribeService(){}
-
-
- @Override
- public IBinder onBind(Intent intent) {
- // TODO: Return the communication channel to the service.
- throw new UnsupportedOperationException("Not yet implemented");
- }
-
-
- @Override
- public void onCreate() {
- super.onCreate();
- // initialize listener
- initializeDiscoveryListener();
- mNsdManager = (NsdManager) this.getSystemService(Context.NSD_SERVICE);
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- mNsdManager.stopServiceDiscovery(mDiscoveryListener);
-
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
-
- if (mNsdManager == null){
- Log.e(TAG, "FATAL ERRO: NSD Manager has not been properly initialized.");
- stopSelf();
- return START_STICKY;
- }
-
- secret = intent.getStringExtra("SECRET");
- activity = JoinGroupActivity.instance;
-
-
- mNsdManager.discoverServices(
- SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
-
- return super.onStartCommand(intent, flags, startId);
- }
-
-
- public void initializeDiscoveryListener() {
- // Instantiate a new DiscoveryListener
- mDiscoveryListener = new NsdManager.DiscoveryListener() {
-
- @Override
- public void onStartDiscoveryFailed(String s, int errorCode ) {
- Log.e(TAG, "Discovery failed: Error code:" + errorCode);
- mNsdManager.stopServiceDiscovery(mDiscoveryListener);
- }
-
- @Override
- public void onStopDiscoveryFailed(String s, int errorCode) {
- Log.e(TAG, "Discovery failed: Error code:" + errorCode);
- mNsdManager.stopServiceDiscovery(mDiscoveryListener);
- }
-
- @Override
- public void onDiscoveryStarted(String s) {
- Log.d(TAG, "Service discovery started: " + s);
- }
-
- @Override
- public void onDiscoveryStopped(String serviceType) {
- Log.i(TAG, "Discovery stopped: " + serviceType);
- }
-
- @Override
- public void onServiceLost(NsdServiceInfo service) {
- // When the network service is no longer available.
- // Internal bookkeeping code goes here.
- Log.e(TAG, "service lost" + service);
- }
-
- @Override
- public void onServiceFound(NsdServiceInfo service) {
- // A service was found! Do something with it.
-
- Log.d(TAG, "onServiceFound: " + service);
-
- if (!service.getServiceType().equals(SERVICE_TYPE)) {
- // Service type is the string containing the protocol and
- // transport layer for this service.
- Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
- } else if (service.getServiceName().equals(SERVICE_NAME)) {
- // The name of the service tells the user what they'd be
- // connecting to. It could be "Bob's Chat App".
- Log.d(TAG, "Same machine: " + SERVICE_NAME);
- } else if (service.getServiceName().contains("SessionPublisher")){
- Log.d(TAG, "Resolve service: ");
- mNsdManager.resolveService(service, new MyResolveListener());
- }
- }
- };
- }
-
- class MyResolveListener implements NsdManager.ResolveListener {
-
-
- @Override
- public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int errorCode) {
- // Called when the resolve fails. Use the error code to debug.
- Log.w(TAG, "Resolve failed" + errorCode);
- }
-
- @Override
- public void onServiceResolved(NsdServiceInfo serviceInfo) {
- Log.w(TAG, "Resolve Succeeded. " + serviceInfo);
-
- if (serviceInfo.getServiceName().equals(SERVICE_NAME)) {
- Log.i(TAG, "Same IP.");
- return;
- }
- mService = serviceInfo;
- Socket socket = null;
- try {
- socket = new Socket(mService.getHost(), mService.getPort());
- } catch (IOException e) {
- Log.e(TAG, "onServiceResolved failed due to socket creation failure.", e);
- return;
- }
-
- NetworkTask networkTask = new NetworkTask();
- networkTask.execute(socket);
- }
- }
-
- /**
- * Have to use AsyncTask since UI Thread is needed to access the group list!
- */
- class NetworkTask extends AsyncTask{
-
- private Socket mSocket;
-
-
- @Override
- protected JSONObject doInBackground(Socket... sockets) {
- mSocket = sockets[0];
- if (mSocket == null){
- return null;
- }
- Log.i("ClientThread", "run()");
- try {
- //String get_message = generateRequest(mHost.getHostAddress(), mPort, "/joinGroup", secret);
- String get_message = generateRequest(mSocket.getInetAddress().toString(), mSocket.getPort(), "/joinGroup", secret);
-
- OutputStream mOutputStream = mSocket.getOutputStream();
-
- PrintWriter wtr = new PrintWriter(mOutputStream);
- wtr.print(get_message);
- wtr.flush();
-
- BufferedReader input = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
-
- String result = parseResponseForBody(input);
-
- JSONObject response = new JSONObject(result);
- boolean success = response.getBoolean("result");
- if (success) {
- Log.w(TAG, "Success response: " + result);
- if (activity != null) {
- // we are calling here activity's method
- return new JSONObject(response.getString("group"));
- }
- } else {
- // do nothing
- Log.w(TAG, "Failure response: " + result);
- return null;
- }
- return null;
- } catch (IOException e) {
- e.printStackTrace();
- } catch (JSONException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(JSONObject simpleGroup) {
- if (mSocket != null && !mSocket.isClosed()){
- try {
- mSocket.close();
- } catch (IOException e) {
- Log.e(TAG, "Failed to close socket");
- }
- }
-
- if (simpleGroup != null) {
- activity.addGroupToList(simpleGroup);
- }
- super.onPostExecute(simpleGroup);
- }
-
- private String parseResponseForBody(BufferedReader input) {
- // parse all header fields
-
- try {
- String statusLine = input.readLine();
-
- if (statusLine == null || statusLine.isEmpty()) {
- return "";
- }
-
- String lengthLine = input.readLine();
- if (lengthLine == null || lengthLine.isEmpty()) {
- return "";
- }
-
- String typeLine = input.readLine();
- if (typeLine == null || typeLine.isEmpty()) {
- return "";
- }
-
- String connectionLine = input.readLine();
- if (connectionLine == null || connectionLine.isEmpty()) {
- return "";
- }
-
- String emptyLine = input.readLine();
- if (emptyLine == null || !emptyLine.isEmpty()){
- return "";
- }
-
- StringBuilder result = new StringBuilder();
- String line;
-
- while ((line = input.readLine()) != null){
- if (line.isEmpty()){
- Log.w(TAG, result.toString());
- break;
- }else {
- result.append(line).append("\r\n");
- }
- }
- return result.toString();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return "";
- }
-
- private String generateRequest(String host, int port, String path, String secret) {
- String accept = "application/json";
- String connect = "Closed";
-
- JSONObject requestBody = new JSONObject();
- try {
- requestBody.put("secret", secret);
- } catch (JSONException e) {
- e.printStackTrace();
- }
-
-
- String request = "GET " + path + " HTTP/1.1\r\n"
- + "Host: " + host + ":" + port + "\r\n"
- + "Accept: " + accept + "\r\n"
- + "Connection: " + connect + "\r\n\r\n"
- + requestBody.toString() + "\r\n"
- + "\r\n";
-
- return request;
- }
- }
-
-}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/CreateGroupActivity.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/CreateGroupActivity.java
index 1f34868..419f076 100644
--- a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/CreateGroupActivity.java
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/CreateGroupActivity.java
@@ -74,7 +74,7 @@ protected void onStop() {
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
- DataService.LocalBinder binder = (DataService.LocalBinder) service;
+ DataService.DataServiceBinder binder = (DataService.DataServiceBinder) service;
mService = binder.getService();
mBound = true;
}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/GroupActivity.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/GroupActivity.java
index 055a597..0755948 100644
--- a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/GroupActivity.java
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/GroupActivity.java
@@ -40,7 +40,7 @@
import ch.ethz.inf.vs.fstreun.finance.Participant;
import ch.ethz.inf.vs.fstreun.finance.SimpleGroup;
import ch.ethz.inf.vs.fstreun.finance.Transaction;
-import ch.ethz.inf.vs.fstreun.network.DataSyncSubscribeService;
+import ch.ethz.inf.vs.fstreun.network.DataSync.Client.DataSyncSubscribeService;
import ch.ethz.inf.vs.fstreun.payapp.ListAdapters.ListParticipantsAdapter;
import ch.ethz.inf.vs.fstreun.payapp.filemanager.DataService;
import ch.ethz.inf.vs.fstreun.payapp.filemanager.FileHelper;
@@ -276,7 +276,7 @@ protected void onStop() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (name.getClassName().equals(DataService.class.getName())){
- DataService.LocalBinder binder = (DataService.LocalBinder) service;
+ DataService.DataServiceBinder binder = (DataService.DataServiceBinder) service;
sessionAccess = binder.getSessionClientAccess(mSimpleGroup.sessionID);
if (sessionAccess == null){
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/JoinGroupActivity.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/JoinGroupActivity.java
index adadd65..841ac6b 100644
--- a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/JoinGroupActivity.java
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/JoinGroupActivity.java
@@ -7,6 +7,7 @@
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
+import android.os.Handler;
import android.os.IBinder;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
@@ -30,25 +31,28 @@
import ch.ethz.inf.vs.fstreun.finance.Group;
import ch.ethz.inf.vs.fstreun.finance.SimpleGroup;
-import ch.ethz.inf.vs.fstreun.network.SessionSubscribeService;
+import ch.ethz.inf.vs.fstreun.network.SessionPublish.Client.GroupSubscribe;
+import ch.ethz.inf.vs.fstreun.network.SessionPublish.Client.GroupSubscribeService;
import ch.ethz.inf.vs.fstreun.payapp.ListAdapters.ListSimpleGroupAdapter;
import ch.ethz.inf.vs.fstreun.payapp.filemanager.DataService;
import ch.ethz.inf.vs.fstreun.payapp.filemanager.FileHelper;
-public class JoinGroupActivity extends AppCompatActivity {
+public class JoinGroupActivity extends AppCompatActivity implements GroupSubscribe.Callback{
+
+ private String TAG = "JoinGroupActivity";
public static JoinGroupActivity instance;
DataService mService;
- private String TAG = "JoinGroupActivity";
boolean mBound;
private Intent intentSessionSubscribeService;
public static final String KEY_SIMPLEGROUP = "simple_group";
- EditText editTextGroupSecret;
+ private EditText editTextGroupSecret;
+ private String currentSecret;
- List groupList = new ArrayList();
- ListSimpleGroupAdapter adapter;
+ private List groupList = new ArrayList();
+ private ListSimpleGroupAdapter adapter;
private SharedPreferences sharedPref;
@Override
@@ -61,6 +65,7 @@ protected void onCreate(Bundle savedInstanceState) {
sharedPref = getSharedPreferences(prefName, Context.MODE_PRIVATE);
editTextGroupSecret = findViewById(R.id.edittext_group_secret);
+ currentSecret = null;
adapter = new ListSimpleGroupAdapter(this, groupList);
ListView listViewFoundGroup = findViewById(R.id.listView_foundGroups);
@@ -73,18 +78,17 @@ public void onItemClick(AdapterView> parent, View view, int position, long id)
}
});
- final Button buttonJoin = findViewById(R.id.button_search);
- buttonJoin.setOnClickListener(new View.OnClickListener() {
+ final Button buttonSearch = findViewById(R.id.button_search);
+ buttonSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- buttonJoinClicked();
+ buttonSearchClicked();
}
});
// for reference in service
instance = this;
-
// Bind to LocalService
Intent intent = new Intent(this, DataService.class);
bindService(intent, mConnection, BIND_AUTO_CREATE);
@@ -133,7 +137,7 @@ protected void onDestroy() {
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
- DataService.LocalBinder binder = (DataService.LocalBinder) service;
+ DataService.DataServiceBinder binder = (DataService.DataServiceBinder) service;
mService = binder.getService();
mBound = true;
}
@@ -145,9 +149,7 @@ public void onServiceDisconnected(ComponentName arg0) {
};
-
-
- private void buttonJoinClicked(){
+ private void buttonSearchClicked(){
// end running
try {
stopService(intentSessionSubscribeService);
@@ -155,30 +157,35 @@ private void buttonJoinClicked(){
}
+ currentSecret = editTextGroupSecret.getText().toString();
+
groupList.clear();
adapter.notifyDataSetChanged();
- String groupHint = editTextGroupSecret.getText().toString();
-
- intentSessionSubscribeService = new Intent(this, SessionSubscribeService.class);
- intentSessionSubscribeService.putExtra("SECRET", groupHint);
+ intentSessionSubscribeService = new Intent(this, GroupSubscribeService.class);
startService(intentSessionSubscribeService);
}
- public void addGroupToList(JSONObject groupJSON){
- Log.d(TAG, "SimpleGroup addGroupToList: " + groupJSON);
- SimpleGroup group = null;
- try {
- group = new SimpleGroup(groupJSON);
- Log.d(TAG, "SimpleGroup added: " + group.toJSON().toString());
- } catch (JSONException e) {
- Log.e(TAG, "Failed to create SimpleGroup from JSON.", e);
- return;
- }
- if (group != null) {
- groupList.add(group);
- adapter.notifyDataSetChanged();
+ public void addGroupToList(String secret, String groupString){
+ if (secret.equals(getSecret())){
+ // still same secret
+
+ Log.d(TAG, "SimpleGroup addGroupToList: " + groupString);
+ SimpleGroup group = null;
+ try {
+ JSONObject groupJSON = new JSONObject(groupString);
+ group = new SimpleGroup(groupJSON);
+ Log.d(TAG, "SimpleGroup added: " + group.toJSON().toString());
+ } catch (JSONException e) {
+ Log.e(TAG, "Failed to create SimpleGroup from JSON.", e);
+ return;
+ }
+ if (group != null) {
+ groupList.add(group);
+ adapter.notifyDataSetChanged();
+ }
+
}
}
@@ -291,4 +298,27 @@ private List loadGroups(){
}
return groups;
}
+
+
+
+ @Override
+ public String getSecret() {
+ return currentSecret;
+ }
+
+ @Override
+ public void groupFound(final String simpleGroup, final String secret) {
+ Log.d(TAG, "groupFound callback");
+
+ // Get a handler that can be used to post to the main thread
+ Handler mainHandler = new Handler(this.getMainLooper());
+
+ Runnable myRunnable = new Runnable() {
+ @Override
+ public void run() {
+ addGroupToList(secret, simpleGroup);
+ } // This is your code
+ };
+ mainHandler.post(myRunnable);
+ }
}
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/MainActivity.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/MainActivity.java
index c90b4a8..591f520 100644
--- a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/MainActivity.java
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/MainActivity.java
@@ -32,8 +32,8 @@
import java.util.Set;
import ch.ethz.inf.vs.fstreun.finance.SimpleGroup;
-import ch.ethz.inf.vs.fstreun.network.DataSyncPublishService;
-import ch.ethz.inf.vs.fstreun.network.DataSyncSubscribeService;
+import ch.ethz.inf.vs.fstreun.network.DataSync.Server.DataSyncPublishService;
+import ch.ethz.inf.vs.fstreun.network.DataSync.Client.DataSyncSubscribeService;
import ch.ethz.inf.vs.fstreun.payapp.ListAdapters.ListGroupAdapter;
import ch.ethz.inf.vs.fstreun.payapp.filemanager.DataService;
@@ -124,7 +124,7 @@ protected void onDestroy() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (name.getClassName().equals(DataService.class.getName())){
- DataService.LocalBinder binder = (DataService.LocalBinder) service;
+ DataService.DataServiceBinder binder = (DataService.DataServiceBinder) service;
dataService = binder.getService();
bound = true;
Log.d(TAG, "onServiceConnected: " + name.getClassName());
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/PublishGroupActivity.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/PublishGroupActivity.java
index 34edb2d..29d1223 100644
--- a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/PublishGroupActivity.java
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/PublishGroupActivity.java
@@ -17,12 +17,12 @@
import java.util.Random;
import ch.ethz.inf.vs.fstreun.finance.SimpleGroup;
-import ch.ethz.inf.vs.fstreun.network.SessionPublishService;
+import ch.ethz.inf.vs.fstreun.network.SessionPublish.Server.GroupPublishService;
public class PublishGroupActivity extends AppCompatActivity {
boolean bound;
- SessionPublishService.LocalBinder serviceBind;
+ GroupPublishService.LocalBinder serviceBind;
private String TAG = "PublishGroupActivity";
public final static String KEY_SIMPLEGROUP = "key_group";
@@ -57,7 +57,7 @@ protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "start service");
// bind service with simplegroup (secret is set with bound service)
- intentSessionPublishService = new Intent(this, SessionPublishService.class);
+ intentSessionPublishService = new Intent(this, GroupPublishService.class);
startService(intentSessionPublishService);
bindService(intentSessionPublishService, connection, BIND_AUTO_CREATE);
}
@@ -69,8 +69,8 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "Service bound: " + name.getClassName());
- if (name.getClassName().equals(SessionPublishService.class.getName())){
- serviceBind = (SessionPublishService.LocalBinder) service;
+ if (name.getClassName().equals(GroupPublishService.class.getName())){
+ serviceBind = (GroupPublishService.LocalBinder) service;
bound = true;
// create random 4 digit number
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/TransactionListActivity.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/TransactionListActivity.java
index 720e364..1da175b 100644
--- a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/TransactionListActivity.java
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/TransactionListActivity.java
@@ -35,7 +35,7 @@
import ch.ethz.inf.vs.fstreun.finance.Group;
import ch.ethz.inf.vs.fstreun.finance.SimpleGroup;
import ch.ethz.inf.vs.fstreun.finance.Transaction;
-import ch.ethz.inf.vs.fstreun.network.DataSyncSubscribeService;
+import ch.ethz.inf.vs.fstreun.network.DataSync.Client.DataSyncSubscribeService;
import ch.ethz.inf.vs.fstreun.payapp.ListAdapters.ListTransactionAdapter;
import ch.ethz.inf.vs.fstreun.payapp.filemanager.DataService;
import ch.ethz.inf.vs.fstreun.payapp.filemanager.FileHelper;
@@ -355,7 +355,7 @@ protected void onDestroy() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (name.getClassName().equals(DataService.class.getName())){
- DataService.LocalBinder binder = (DataService.LocalBinder) service;
+ DataService.DataServiceBinder binder = (DataService.DataServiceBinder) service;
sessionAccess = binder.getSessionClientAccess(group.getSessionID());
if(sessionAccess != null) {
diff --git a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/filemanager/DataService.java b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/filemanager/DataService.java
index 85b0f96..6f1d6af 100644
--- a/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/filemanager/DataService.java
+++ b/app/src/main/java/ch/ethz/inf/vs/fstreun/payapp/filemanager/DataService.java
@@ -107,13 +107,13 @@ private void storeSessionIDs(Set sessionIDs){
*/
// Binder given to clients
- private final IBinder mBinder = new LocalBinder();
+ private final IBinder mBinder = new DataServiceBinder();
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
- public class LocalBinder extends Binder {
+ public class DataServiceBinder extends Binder {
/**
* Return this instance of LocalService so clients can call public methods
diff --git a/app/src/main/res/drawable/ic_search_black_24dp.xml b/app/src/main/res/drawable/ic_search_black_24dp.xml
new file mode 100644
index 0000000..affc7ba
--- /dev/null
+++ b/app/src/main/res/drawable/ic_search_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_join_group.xml b/app/src/main/res/layout/activity_join_group.xml
index 192f38a..c4b4e12 100644
--- a/app/src/main/res/layout/activity_join_group.xml
+++ b/app/src/main/res/layout/activity_join_group.xml
@@ -12,28 +12,41 @@
android:padding="8dp"
android:text="Search group with secret." />
-
-
-