Commit 1be9caac authored by LIly's avatar LIly

using bluetooth instead of wifi..

parent d7537066
...@@ -47,7 +47,7 @@ android { ...@@ -47,7 +47,7 @@ android {
} }
dependencies { dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: '../ebclibrary/libs')
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations' exclude group: 'com.android.support', module: 'support-annotations'
}) })
......
...@@ -24,7 +24,9 @@ import org.mpisws.messaging.ReceivedMessageWrapper; ...@@ -24,7 +24,9 @@ import org.mpisws.messaging.ReceivedMessageWrapper;
import org.mpisws.testapp.googleauth.GoogleNativeAuthenticator; import org.mpisws.testapp.googleauth.GoogleNativeAuthenticator;
import org.mpisws.testapp.googleauth.GoogleToken; import org.mpisws.testapp.googleauth.GoogleToken;
import org.mpisws.testapp.simulator.SimulationClient; import org.mpisws.testapp.simulator.SimulationClient;
import org.mpisws.testapp.simulator.SimulationClientBT;
import org.mpisws.testapp.simulator.SimulationServer; import org.mpisws.testapp.simulator.SimulationServer;
import org.mpisws.testapp.simulator.SimulationServerBT;
import java.util.List; import java.util.List;
...@@ -54,7 +56,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe ...@@ -54,7 +56,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
findViewById(R.id.signIn).setOnClickListener(this); findViewById(R.id.signIn).setOnClickListener(this);
findViewById(R.id.signOut).setOnClickListener(this); findViewById(R.id.signOut).setOnClickListener(this);
findViewById(R.id.deleteAccount).setOnClickListener(this); findViewById(R.id.deleteAccount).setOnClickListener(this);
findViewById(R.id.testESFunctions).setOnClickListener(this);
findViewById(R.id.testSendMessages).setOnClickListener(this); findViewById(R.id.testSendMessages).setOnClickListener(this);
findViewById(R.id.testReceiveMessages).setOnClickListener(this); findViewById(R.id.testReceiveMessages).setOnClickListener(this);
findViewById(R.id.simulateEncounterFormationAndConfirmationClient).setOnClickListener(this); findViewById(R.id.simulateEncounterFormationAndConfirmationClient).setOnClickListener(this);
...@@ -95,11 +96,12 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe ...@@ -95,11 +96,12 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
/***************************** ES AND SDDR TESTS **********************/ /***************************** ES AND SDDR TESTS **********************/
case R.id.simulateEncounterFormationAndConfirmationClient: case R.id.simulateEncounterFormationAndConfirmationClient:
if (!isSignedIn()) throw new SecurityException("Not signed in"); if (!isSignedIn()) throw new SecurityException("Not signed in");
new SimulationClient(this).sendDataToSimulationServerAndStartCore(); new SimulationClientBT(this).startClient();
break; break;
case R.id.simulateEncounterFormationAndConfirmationServer: case R.id.simulateEncounterFormationAndConfirmationServer:
if (!isSignedIn()) throw new SecurityException("Not signed in"); if (!isSignedIn()) throw new SecurityException("Not signed in");
new SimulationServer(this).startServer(); Log.d(TAG, "Starting simulation server!");
new SimulationServerBT(this).startServer();
break; break;
case R.id.testSendMessages: case R.id.testSendMessages:
ebc.getSDDRClient().updateDatabaseOnAgent(); ebc.getSDDRClient().updateDatabaseOnAgent();
......
...@@ -35,8 +35,8 @@ public class SimulationClient { ...@@ -35,8 +35,8 @@ public class SimulationClient {
protected static List<Identifier> mSharedSecrets = new ArrayList<>(NUM_SIMULATED_DEVICES*NUM_SIMULATED_EPOCHS); protected static List<Identifier> mSharedSecrets = new ArrayList<>(NUM_SIMULATED_DEVICES*NUM_SIMULATED_EPOCHS);
protected static int CURRENT_EPOCH = 0; protected static int CURRENT_EPOCH = 0;
static private String mServiceName = "EbCSimulator"; static protected String mServiceName = "EbCSimulation";
static private String mServiceType = "_ebcsimulator._tcp"; static protected String mServiceType = "_http._tcp";
private NsdManager.DiscoveryListener mDiscoveryListener; private NsdManager.DiscoveryListener mDiscoveryListener;
private NsdManager mNsdManager; private NsdManager mNsdManager;
...@@ -99,7 +99,7 @@ public class SimulationClient { ...@@ -99,7 +99,7 @@ public class SimulationClient {
// Service type is the string containing the protocol and // Service type is the string containing the protocol and
// transport layer for this service. // transport layer for this service.
Log.d(TAG, "Unknown Service Type: " + service.getServiceType()); Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
} else if (service.getServiceName().contains("EbCSimulator")){ } else if (service.getServiceName().contains(mServiceName)){
mNsdManager.resolveService(service, mResolveListener); mNsdManager.resolveService(service, mResolveListener);
} }
} }
......
package org.mpisws.testapp.simulator;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import org.mpisws.encounters.encounterformation.SDDR_Native;
import org.mpisws.helpers.Identifier;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.List;
import java.util.UUID;
import static org.mpisws.testapp.simulator.SimulationClient.NUM_SIMULATED_DEVICES;
import static org.mpisws.testapp.simulator.SimulationClient.NUM_SIMULATED_EPOCHS;
import static org.mpisws.testapp.simulator.SimulationClient.mDHFullKeys;
import static org.mpisws.testapp.simulator.SimulationClient.mDHNonces;
import static org.mpisws.testapp.simulator.SimulationClient.mDHPubKeys;
import static org.mpisws.testapp.simulator.SimulationClient.mSharedSecrets;
import static org.mpisws.testapp.simulator.SimulationClient.otherDHFullKeys;
import static org.mpisws.testapp.simulator.SimulationClient.otherDHNonces;
import static org.mpisws.testapp.simulator.SimulationClient.otherDHPubKeys;
/**
* This class does all the work for setting up and managing Bluetooth
* connections with other devices. It has a thread that listens for
* incoming connections, a thread for connecting with a device, and a
* thread for performing data transmissions when connected.
*/
public class SimulationClientBT {
Context context;
private static final String TAG = SimulationClientBT.class.getSimpleName();
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
private final BluetoothAdapter mAdapter;
static private SimulatorEncounterFormationCore core;
public SimulationClientBT(Context context) {
this.context = context;
mAdapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
context.registerReceiver(mReceiver, filter);
core = new SimulatorEncounterFormationCore(context);
initializeSimulatedAdverts();
}
public void startClient() {
mAdapter.cancelDiscovery();
Log.d(TAG, "Starting discovery");
mAdapter.startDiscovery();
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "Device found: " + device.getName() + "; MAC " + device.getAddress());
if (device.getName() != null && device.getName().contains("Xperia")) {
connect(device);
context.unregisterReceiver(mReceiver);
mAdapter.cancelDiscovery();
}
}
}
};
private void connect(BluetoothDevice device) {
new Thread( () -> {
BluetoothSocket sock;
try {
sock = device.createRfcommSocketToServiceRecord(MY_UUID);
sock.connect();
Log.d(TAG, "Connected, sending DH keys over socket");
sendDHKeysOverSocket(sock);
sock.close();
} catch (IOException e) {
Log.d(TAG, "Exception: " + e);
}
}).start();
}
private void initializeSimulatedAdverts() {
for (int i = 0; i < NUM_SIMULATED_EPOCHS*NUM_SIMULATED_DEVICES; i++) {
SDDR_Native.c_changeEpoch();
otherDHPubKeys.add(new Identifier(SDDR_Native.c_getAdvertDHPubKey()));
otherDHFullKeys.add(new Identifier(SDDR_Native.c_getAdvertDHKey()));
otherDHNonces.add(new Identifier(SDDR_Native.c_getMyAdvert()));
}
for (int i = 0; i < NUM_SIMULATED_EPOCHS; i++) {
SDDR_Native.c_changeEpoch();
mDHPubKeys.add(new Identifier(SDDR_Native.c_getAdvertDHPubKey()));
mDHFullKeys.add(new Identifier(SDDR_Native.c_getAdvertDHKey()));
mDHNonces.add(new Identifier(SDDR_Native.c_getMyAdvert()));
for (int j = 0; j < NUM_SIMULATED_DEVICES; j++) {
Identifier sharedSecret = new Identifier(SDDR_Native.c_computeSecretKeyWithSHA(
otherDHFullKeys.get(j+(NUM_SIMULATED_DEVICES*i)).getBytes(),
mDHNonces.get(i).getBytes(),
mDHPubKeys.get(i).getBytes()));
mSharedSecrets.add(sharedSecret);
}
}
}
private void sendDHKeysOverSocket(BluetoothSocket sock) {
try {
if (sock == null) return;
String serializedSecrets;
String serializedNonces;
String serializedPubKeys;
// serialize
OutputStream os = sock.getOutputStream();
try {
serializedSecrets = serializeList(mSharedSecrets);
serializedNonces = serializeList(otherDHNonces);
serializedPubKeys = serializeList(otherDHPubKeys);
} catch (Exception e) {
System.out.println(e);
return;
}
PrintWriter pw = new PrintWriter(os, true);
pw.println(serializedSecrets + serializedNonces + serializedPubKeys + "\r\n");
Log.d(TAG, "Lengths: " + serializedSecrets.length() + ", " + serializedNonces.length() + "," + serializedPubKeys.length());
Log.d(TAG, "Sent data over socket!");
BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
String line = in.readLine();
Log.d(TAG, "Got response: " + line);
in.close();
pw.close();
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
// run the simulator core
Log.d(TAG, "Running simulator core!");
new Thread(core).start();
}
private String serializeList(List<Identifier> list) throws IOException {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream so = new ObjectOutputStream(bo);
so.writeObject(mSharedSecrets);
so.flush();
Log.d(TAG, "Serialized string to " + bo.toString());
return bo.toString();
}
}
...@@ -29,12 +29,12 @@ import static org.mpisws.encounters.EncounterBasedCommunication.CHANGE_EPOCH_TIM ...@@ -29,12 +29,12 @@ import static org.mpisws.encounters.EncounterBasedCommunication.CHANGE_EPOCH_TIM
import static org.mpisws.helpers.Utils.SHA1; import static org.mpisws.helpers.Utils.SHA1;
import static org.mpisws.testapp.simulator.SimulationClient.NUM_SIMULATED_DEVICES; import static org.mpisws.testapp.simulator.SimulationClient.NUM_SIMULATED_DEVICES;
import static org.mpisws.testapp.simulator.SimulationClient.NUM_SIMULATED_EPOCHS; import static org.mpisws.testapp.simulator.SimulationClient.NUM_SIMULATED_EPOCHS;
import static org.mpisws.testapp.simulator.SimulationClient.mServiceName;
import static org.mpisws.testapp.simulator.SimulationClient.mServiceType;
public class SimulationServer { public class SimulationServer {
private static final String TAG = SimulationServer.class.getSimpleName(); private static final String TAG = SimulationServer.class.getSimpleName();
static private int port; static private int port;
static private String mServiceName = "EbCSimulator";
static private String mServiceType = "_ebcsimulator._tcp";
private int currentEpoch = 0; private int currentEpoch = 0;
private ServerSocket mServerSocket; private ServerSocket mServerSocket;
...@@ -53,37 +53,13 @@ public class SimulationServer { ...@@ -53,37 +53,13 @@ public class SimulationServer {
// Initialize a server socket on the next available port. // Initialize a server socket on the next available port.
try { try {
mServerSocket = new ServerSocket(0); mServerSocket = new ServerSocket(0);
} catch (IOException e) {
// Store the chosen port.
port = mServerSocket.getLocalPort();
registerService(port);
Socket sock = mServerSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
List<String> lines = new ArrayList<>();
String line;
while ((line = in.readLine()) != null) {
lines.add(line);
}
PrintStream output = new PrintStream(sock.getOutputStream());
output.println("Finished");
Utils.myAssert(lines.size() == 3);
sharedSecrets = deserializeIDList(lines.get(0));
nonces = deserializeIDList(lines.get(1));
pubKeys = deserializeIDList(lines.get(2));
if (sharedSecrets == null || nonces == null || pubKeys == null) {
return;
}
output.close();
in.close();
sock.close();
processData();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
// Store the chosen port.
port = mServerSocket.getLocalPort();
Log.d(TAG, "Simulation Server opened on port " + port);
registerService(port);
}).start(); }).start();
} }
...@@ -150,12 +126,13 @@ public class SimulationServer { ...@@ -150,12 +126,13 @@ public class SimulationServer {
serviceInfo.setPort(port); serviceInfo.setPort(port);
initializeRegistrationListener(); initializeRegistrationListener();
Log.d(TAG, "Registering service");
mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener); mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
} }
private void initializeRegistrationListener() { private void initializeRegistrationListener() {
Log.d(TAG, "Initializing registration listener");
mRegistrationListener = new NsdManager.RegistrationListener() { mRegistrationListener = new NsdManager.RegistrationListener() {
@Override @Override
public void onServiceRegistered(NsdServiceInfo NsdServiceInfo) { public void onServiceRegistered(NsdServiceInfo NsdServiceInfo) {
// Save the service name. Android may have changed it in order to // Save the service name. Android may have changed it in order to
...@@ -163,6 +140,36 @@ public class SimulationServer { ...@@ -163,6 +140,36 @@ public class SimulationServer {
// with the name Android actually used. // with the name Android actually used.
mServiceName = NsdServiceInfo.getServiceName(); mServiceName = NsdServiceInfo.getServiceName();
Log.d(TAG, "Registration success " + mServiceName); Log.d(TAG, "Registration success " + mServiceName);
try {
Socket sock = mServerSocket.accept();
Log.d(TAG, "Accepted sock connection");
BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
List<String> lines = new ArrayList<>();
String line;
while ((line = in.readLine()) != null) {
lines.add(line);
}
PrintStream output = new PrintStream(sock.getOutputStream());
output.println("Finished");
Utils.myAssert(lines.size() == 3);
sharedSecrets = deserializeIDList(lines.get(0));
nonces = deserializeIDList(lines.get(1));
pubKeys = deserializeIDList(lines.get(2));
if (sharedSecrets == null || nonces == null || pubKeys == null) {
return;
}
output.close();
in.close();
sock.close();
mNsdManager.unregisterService(this);
processData();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
} }
@Override @Override
...@@ -172,13 +179,14 @@ public class SimulationServer { ...@@ -172,13 +179,14 @@ public class SimulationServer {
@Override @Override
public void onServiceUnregistered(NsdServiceInfo arg0) { public void onServiceUnregistered(NsdServiceInfo arg0) {
Log.d(TAG, "Registration listener unregistered");
// Service has been unregistered. This only happens when you call // Service has been unregistered. This only happens when you call
// NsdManager.unregisterService() and pass in this listener. // NsdManager.unregisterService() and pass in this listener.
} }
@Override @Override
public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
// Unregistration failed. Put debugging code here to determine why. Log.d(TAG, "UnRegistration listener failed " + errorCode);
} }
}; };
} }
......
package org.mpisws.testapp.simulator;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.util.Log;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.mpisws.embeddedsocial.ESClient;
import org.mpisws.embeddedsocial.ESMessage;
import org.mpisws.helpers.Identifier;
import org.mpisws.helpers.Utils;
import org.mpisws.messaging.EpochLinkMessage;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import static org.mpisws.encounters.EncounterBasedCommunication.CHANGE_EPOCH_TIME;
import static org.mpisws.helpers.Utils.SHA1;
import static org.mpisws.testapp.simulator.SimulationClient.NUM_SIMULATED_DEVICES;
import static org.mpisws.testapp.simulator.SimulationClient.NUM_SIMULATED_EPOCHS;
/**
* This class does all the work for setting up and managing Bluetooth
* connections with other devices. It has a thread that listens for
* incoming connections, a thread for connecting with a device, and a
* thread for performing data transmissions when connected.
*/
public class SimulationServerBT {
private static final String TAG = SimulationServerBT.class.getSimpleName();
private static final String NAME = "SimulationServerBT";
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
private final BluetoothAdapter mAdapter;
private Context context;
private int currentEpoch = 0;
private List<Identifier> nonces;
private List<Identifier> sharedSecrets;
private List<Identifier> pubKeys;
/**
*/
public SimulationServerBT(Context context) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
this.context = context;
}
public void startServer() {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
context.startActivity(discoverableIntent);
new Thread( () -> {
Log.d(TAG, "start");
BluetoothSocket socket;
// Create a new listening server socket
try {
BluetoothServerSocket serversocket = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
Log.d(TAG, "accepting");
socket = serversocket.accept();
Log.d(TAG, "accepted");
serversocket.close();
// If a connection was accepted
if (socket != null) {
DataInputStream in = new DataInputStream(socket.getInputStream());
byte[] messageByte = new byte[1000];
boolean end = false;
String dataString = "";
while(true)
{
int bytesRead = in.read(messageByte);
dataString += new String(messageByte, 0, bytesRead);
Log.d(TAG, dataString);
if (dataString.contains(java.util.regex.Pattern.quote("\r\n"))) {
break;
}
}
dataString.substring(0, dataString.indexOf(java.util.regex.Pattern.quote("\r\n")));
sharedSecrets = deserializeIDList(dataString.substring(0, dataString.length()/3));
nonces = deserializeIDList(dataString.substring(dataString.length()/3, 2*dataString.length()/3));
pubKeys = deserializeIDList(dataString.substring(2*dataString.length()/3));
if (sharedSecrets == null || nonces == null || pubKeys == null) {
return;
}
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
pw.println("Finished");
pw.close();
in.close();
socket.close();
processData();
} else {
Log.d(TAG, "Socket was null");
}
} catch (IOException | ClassNotFoundException e) {
Log.e(TAG, "IO exception trying to accept and read " + e.getMessage());
}
}).start();
}
private List<Identifier> deserializeIDList(String serializedObject) throws IOException, ClassNotFoundException {
byte b[] = serializedObject.getBytes();
ByteArrayInputStream bi = new ByteArrayInputStream(b);
ObjectInputStream si = new ObjectInputStream(bi);
List<Identifier> obj = (List<Identifier>) si.readObject();
return obj;
}
private void processData() {
// Create all topics you'll ever have to create
List<Pair<Identifier, Identifier>> topicsToCreate = new ArrayList<>();
for (int i=0; i < nonces.size(); i++) {
topicsToCreate.add(new ImmutablePair<>(nonces.get(i), pubKeys.get(i)));
}
for (Identifier ss : sharedSecrets) {
topicsToCreate.add(new ImmutablePair<>(ss, ss));
}
Log.d(TAG, "Creating topics: " + topicsToCreate.size());
ESClient.getInstance().createTopics(topicsToCreate);
// Every "epoch" or so try to post link messages to the prior "epoch" ss for each "device"
// Let's try and post to the prior 3 epochs
new Handler().postDelayed(() -> {
int lowEpoch = currentEpoch > 3 ? currentEpoch - 3 : 0;
List<Identifier> sses = sharedSecrets.subList(lowEpoch*NUM_SIMULATED_DEVICES, currentEpoch*NUM_SIMULATED_DEVICES);
List<String> topicHandles = ESClient.getInstance().getTopicHandles(sses);
List<ESMessage> msgsToSend = new ArrayList<>();
for (int i = 0; i < NUM_SIMULATED_DEVICES; i++) {
for (int j = currentEpoch+1; j > lowEpoch+1; j--) {
int oldIndex = (j-1-lowEpoch)*NUM_SIMULATED_DEVICES + i;
int newIndex = (j-lowEpoch)*NUM_SIMULATED_DEVICES + i;
if (topicHandles.get(oldIndex) == null || topicHandles.get(oldIndex).compareTo("") == 0) {
continue;
}
EpochLinkMessage epochLinkMessage = new EpochLinkMessage.EpochLinkMessageBuilder()
.addOldNonce(nonces.get((lowEpoch*NUM_SIMULATED_DEVICES) + oldIndex).toString())
.addNewNonce(nonces.get((lowEpoch*NUM_SIMULATED_DEVICES) + newIndex