mirror of
https://github.com/DanielPollithy/flashwifi.git
synced 2025-10-16 11:45:32 +00:00
Merge branch 'master' of https://github.com/DanielPollithy/flashwifi
This commit is contained in:
commit
01646644d1
7
Daniel.txt
Normal file
7
Daniel.txt
Normal file
@ -0,0 +1,7 @@
|
||||
- add toggle button to action bar
|
||||
- forget networks after discovery
|
||||
- stop discovery after successful negotiation
|
||||
- display states in frontend
|
||||
- p2p discovery active -> stop button
|
||||
- negotiation sockets active -> stop button
|
||||
- refactor NegotiationClientTask and NegotiationServerTask ( -> common code base)
|
||||
@ -34,12 +34,8 @@
|
||||
android:parentActivityName=".DesktopActivity" />
|
||||
|
||||
<service
|
||||
android:name=".WiFiDirectBroadcastService"
|
||||
android:name=".broadcast.WiFiDirectBroadcastService"
|
||||
android:description="@string/wifi_direct" />
|
||||
<service
|
||||
android:name=".MessengerService"
|
||||
android:process=":remote" />
|
||||
<service android:name=".AccessPointService" />
|
||||
|
||||
<activity android:name=".DesktopActivity" />
|
||||
|
||||
|
||||
@ -12,10 +12,8 @@ import android.net.wifi.p2p.WifiP2pManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
@ -27,6 +25,8 @@ import android.widget.Toast;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.flashwifi.wifip2p.broadcast.WiFiDirectBroadcastService;
|
||||
|
||||
|
||||
public class ChatActivity extends AppCompatActivity {
|
||||
|
||||
@ -38,7 +38,7 @@ public class ChatActivity extends AppCompatActivity {
|
||||
String address;
|
||||
|
||||
WiFiDirectBroadcastService mService;
|
||||
AccessPointService apService;
|
||||
//AccessPointService apService;
|
||||
boolean mBound = false;
|
||||
InetAddress groupOwnerAddress;
|
||||
|
||||
@ -65,8 +65,8 @@ public class ChatActivity extends AppCompatActivity {
|
||||
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
||||
|
||||
// Bind to
|
||||
Intent intent2 = new Intent(this, AccessPointService.class);
|
||||
bindService(intent2, apConnection, Context.BIND_AUTO_CREATE);
|
||||
//Intent intent2 = new Intent(this, AccessPointService.class);
|
||||
//bindService(intent2, apConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
private void updateUi(Intent intent) {
|
||||
@ -132,7 +132,7 @@ public class ChatActivity extends AppCompatActivity {
|
||||
public void onClick(final View view) {
|
||||
addMessageRight(name, input.getText().toString());
|
||||
// send the message to the peer
|
||||
mService.sendMessageToSocketServer(groupOwnerAddress, input.getText().toString());
|
||||
//mService.sendMessageToSocketServer(groupOwnerAddress, input.getText().toString());
|
||||
}
|
||||
});
|
||||
|
||||
@ -160,17 +160,17 @@ public class ChatActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void startHotspot() {
|
||||
apService.startAP();
|
||||
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
|
||||
fab.setImageResource(R.drawable.icon_tethering_on);
|
||||
hotspot_running = true;
|
||||
//apService.startAP();
|
||||
//FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
|
||||
//fab.setImageResource(R.drawable.icon_tethering_on);
|
||||
//hotspot_running = true;
|
||||
}
|
||||
|
||||
private void stopHotspot() {
|
||||
apService.stopAP();
|
||||
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
|
||||
fab.setImageResource(R.drawable.icon_tethering_off);
|
||||
hotspot_running = false;
|
||||
//apService.stopAP();
|
||||
//FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
|
||||
//fab.setImageResource(R.drawable.icon_tethering_off);
|
||||
//hotspot_running = false;
|
||||
}
|
||||
|
||||
public void addMessageLeft(String name, String text) {
|
||||
@ -207,24 +207,4 @@ public class ChatActivity extends AppCompatActivity {
|
||||
}
|
||||
};
|
||||
|
||||
/** Defines callbacks for service binding, passed to bindService() */
|
||||
private ServiceConnection apConnection = new ServiceConnection() {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className,
|
||||
IBinder service) {
|
||||
// We've bound to LocalService, cast the IBinder and get LocalService instance
|
||||
AccessPointService.LocalBinder binder = (AccessPointService.LocalBinder) service;
|
||||
apService = binder.getService();
|
||||
//apBound = true;
|
||||
// start connection
|
||||
connectToPeer(address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName arg0) {
|
||||
mBound = false;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -1,57 +0,0 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
public class ClientTask extends AsyncTask<String, Void, String> {
|
||||
|
||||
private final static String TAG = "ClientTask";
|
||||
|
||||
@Override
|
||||
protected String doInBackground(String... params) {
|
||||
String host = params[0];
|
||||
String message = params[1];
|
||||
int port = 9999;
|
||||
Socket socket = new Socket();
|
||||
Log.d(TAG, "connectToSocketServer: socket created");
|
||||
byte buf[] = new byte[1024];
|
||||
try {
|
||||
socket.bind(null);
|
||||
Log.d(TAG, "connectToSocketServer: socket bind");
|
||||
socket.connect((new InetSocketAddress(host, port)), 500);
|
||||
Log.d(TAG, "connectToSocketServer: socket connected");
|
||||
DataOutputStream DOS = new DataOutputStream(socket.getOutputStream());
|
||||
DOS.writeUTF(message);
|
||||
Log.d(TAG, "connectToSocketServer: utf written");
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
//catch logic
|
||||
Log.d(TAG, "connectToSocketServer: io exception");
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
if (socket.isConnected()) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
//catch logic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Void... values) {}
|
||||
}
|
||||
@ -9,37 +9,22 @@ import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.wifi.p2p.WifiP2pDevice;
|
||||
import android.net.wifi.p2p.WifiP2pGroup;
|
||||
import android.net.wifi.p2p.WifiP2pInfo;
|
||||
import android.net.wifi.p2p.WifiP2pManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ToggleButton;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import jota.IotaAPI;
|
||||
import jota.dto.response.GetNodeInfoResponse;
|
||||
import com.flashwifi.wifip2p.broadcast.WiFiDirectBroadcastService;
|
||||
|
||||
|
||||
public class HotspotFragment extends Fragment {
|
||||
|
||||
@ -1,134 +0,0 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class MessengerService extends Service {
|
||||
/** For showing and hiding our notification. */
|
||||
NotificationManager mNM;
|
||||
/** Keeps track of all current registered clients. */
|
||||
static ArrayList<Messenger> mClients = new ArrayList<Messenger>();
|
||||
/** Holds last value set by a client. */
|
||||
static int mValue = 0;
|
||||
|
||||
/**
|
||||
* Command to the service to register a client, receiving callbacks
|
||||
* from the service. The Message's replyTo field must be a Messenger of
|
||||
* the client where callbacks should be sent.
|
||||
*/
|
||||
static final int MSG_REGISTER_CLIENT = 1;
|
||||
|
||||
/**
|
||||
* Command to the service to unregister a client, ot stop receiving callbacks
|
||||
* from the service. The Message's replyTo field must be a Messenger of
|
||||
* the client as previously given with MSG_REGISTER_CLIENT.
|
||||
*/
|
||||
static final int MSG_UNREGISTER_CLIENT = 2;
|
||||
|
||||
/**
|
||||
* Command to service to set a new value. This can be sent to the
|
||||
* service to supply a new value, and will be sent by the service to
|
||||
* any registered clients with the new value.
|
||||
*/
|
||||
static final int MSG_SET_VALUE = 3;
|
||||
|
||||
/**
|
||||
* Handler of incoming messages from clients.
|
||||
*/
|
||||
static class IncomingHandler extends Handler {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_REGISTER_CLIENT:
|
||||
mClients.add(msg.replyTo);
|
||||
break;
|
||||
case MSG_UNREGISTER_CLIENT:
|
||||
mClients.remove(msg.replyTo);
|
||||
break;
|
||||
case MSG_SET_VALUE:
|
||||
mValue = msg.arg1;
|
||||
for (int i=mClients.size()-1; i>=0; i--) {
|
||||
try {
|
||||
mClients.get(i).send(Message.obtain(null,
|
||||
MSG_SET_VALUE, mValue, 0));
|
||||
} catch (RemoteException e) {
|
||||
// The client is dead. Remove it from the list;
|
||||
// we are going through the list from back to front
|
||||
// so this is safe to do inside the loop.
|
||||
mClients.remove(i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
super.handleMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Target we publish for clients to send messages to IncomingHandler.
|
||||
*/
|
||||
final Messenger mMessenger = new Messenger(new IncomingHandler());
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||
|
||||
// Display a notification about us starting.
|
||||
showNotification();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
// Cancel the persistent notification.
|
||||
mNM.cancel(R.string.remote_service_started);
|
||||
|
||||
// Tell the user we stopped.
|
||||
Toast.makeText(this, R.string.remote_service_stopped, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
/**
|
||||
* When binding to the service, we return an interface to our messenger
|
||||
* for sending messages to the service.
|
||||
*/
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mMessenger.getBinder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a notification while this service is running.
|
||||
*/
|
||||
private void showNotification() {
|
||||
// In this sample, we'll use the same text for the ticker and the expanded notification
|
||||
CharSequence text = getText(R.string.remote_service_started);
|
||||
|
||||
// The PendingIntent to launch our activity if the user selects this notification
|
||||
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
|
||||
new Intent(this, ChatActivity.class), 0);
|
||||
|
||||
// Set the info for the views that show in the notification panel.
|
||||
Notification notification = new Notification.Builder(this)
|
||||
.setTicker(text) // the status text
|
||||
.setWhen(System.currentTimeMillis()) // the time stamp
|
||||
.setContentTitle(getText(R.string.local_service_label)) // the label of the entry
|
||||
.setContentText(text) // the contents of the entry
|
||||
.setContentIntent(contentIntent) // The intent to send when the entry is clicked
|
||||
.build();
|
||||
|
||||
// Send the notification.
|
||||
// We use a string id because it is a unique number. We use it later to cancel.
|
||||
mNM.notify(R.string.remote_service_started, notification);
|
||||
}
|
||||
}
|
||||
@ -1,273 +0,0 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import com.flashwifi.wifip2p.datastore.PeerStore;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationFinalization;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOffer;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOfferAnswer;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
|
||||
|
||||
public class NegotiationClientTask extends AsyncTask<String, Void, String> {
|
||||
|
||||
private static final String TAG = "NegClientTask";
|
||||
|
||||
private boolean running = true;
|
||||
private Socket socket;
|
||||
private NegotiationServerTask.State server_state;
|
||||
private NegotiationClientTask.State client_state;
|
||||
|
||||
BufferedReader in;
|
||||
PrintWriter out;
|
||||
private boolean isClient = false;
|
||||
|
||||
public String getLine() {
|
||||
String response;
|
||||
try {
|
||||
response = in.readLine();
|
||||
} catch (IOException ex) {
|
||||
response = "Error: " + ex;
|
||||
}
|
||||
Log.d(TAG, "getLine: " + response);
|
||||
return response;
|
||||
}
|
||||
|
||||
private void sendLine(String line) {
|
||||
out.println(line);
|
||||
Log.d(TAG, "sendLine: " + line);
|
||||
}
|
||||
|
||||
public void writeError(int code, String msg) {
|
||||
sendLine(String.format("err_code: %s msg: %s", Integer.toString(code), msg));
|
||||
}
|
||||
|
||||
private boolean runClient(String ipAddressString, boolean isClient, String macAddress) {
|
||||
boolean success = false;
|
||||
|
||||
try {
|
||||
client_state = State.INITIAL;
|
||||
|
||||
// create socket
|
||||
socket = new Socket(ipAddressString, 9898);
|
||||
// set the socket timeout to 1 second
|
||||
// ToDo: make this a variable
|
||||
socket.setSoTimeout(1000);
|
||||
Log.d(TAG, "doInBackground: client socket created");
|
||||
|
||||
// set up the stream reader and writer
|
||||
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
out = new PrintWriter(socket.getOutputStream(), true);
|
||||
|
||||
// send Client Request
|
||||
String hello = isClient ? "HELLO I AM CLIENT" : "HELLO I AM SERVER";
|
||||
sendLine(hello);
|
||||
|
||||
if (isClient) {
|
||||
success = runClientProtocol(macAddress);
|
||||
} else {
|
||||
success = runServerProtocol(macAddress);
|
||||
}
|
||||
|
||||
} catch (SocketTimeoutException ste) {
|
||||
System.out.println("### Timed out after 1 seconds");
|
||||
} catch (IOException e) {
|
||||
Log.d("", e.getMessage());
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(String... params) {
|
||||
|
||||
String isClientString = params[0];
|
||||
if (isClientString.equals("True")) {
|
||||
isClient = true;
|
||||
}
|
||||
|
||||
String ipAddressString = params[1];
|
||||
|
||||
String macAddress = params[2];
|
||||
|
||||
boolean success = false;
|
||||
|
||||
while (!success){
|
||||
success = runClient(ipAddressString, isClient, macAddress);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private void closeConnection() throws IOException {
|
||||
socket.close();
|
||||
}
|
||||
|
||||
private boolean runClientProtocol(String macAddress) throws IOException {
|
||||
|
||||
Gson gson = new Gson();
|
||||
|
||||
// WAIT FOR OFFER
|
||||
client_state = NegotiationClientTask.State.WAIT_FOR_OFFER;
|
||||
|
||||
String offerString = getLine();
|
||||
if (offerString == null) {
|
||||
closeConnection();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// CHECK OFFER
|
||||
client_state = NegotiationClientTask.State.CHECK_OFFER;
|
||||
|
||||
// Get offer
|
||||
|
||||
NegotiationOffer offer = gson.fromJson(offerString, NegotiationOffer.class);
|
||||
// Write offer to the PeerStore
|
||||
PeerStore.getInstance().setLatestOffer(macAddress, offer);
|
||||
|
||||
// ToDo: implement accept or deny logic
|
||||
if (!true) {
|
||||
client_state = NegotiationClientTask.State.ERROR;
|
||||
writeError(1, "Offer not acceptable");
|
||||
// ToDo: Error handling
|
||||
return false;
|
||||
}
|
||||
|
||||
// SEND NegotiationAnswer
|
||||
NegotiationOfferAnswer answer = new NegotiationOfferAnswer(true, 10);
|
||||
String answerString = gson.toJson(answer);
|
||||
sendLine(answerString);
|
||||
|
||||
// WAIT FOR PASSWORD and hostname
|
||||
client_state = NegotiationClientTask.State.WAIT_FOR_PASSWORD;
|
||||
String finalizationString = getLine();
|
||||
|
||||
if (finalizationString == null) {
|
||||
closeConnection();
|
||||
return false;
|
||||
}
|
||||
|
||||
NegotiationFinalization finalization = gson.fromJson(finalizationString, NegotiationFinalization.class);
|
||||
// Write offer to the PeerStore
|
||||
PeerStore.getInstance().setLatestFinalization(macAddress, finalization);
|
||||
|
||||
|
||||
// Send OK
|
||||
sendLine("OK from Client");
|
||||
client_state = NegotiationClientTask.State.SUCCESS;
|
||||
|
||||
socket.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean runServerProtocol(String macAddress) throws IOException {
|
||||
// Json serializer
|
||||
Gson gson = new GsonBuilder().create();
|
||||
|
||||
|
||||
// CHECK_CLIENT_REQUEST
|
||||
server_state = NegotiationServerTask.State.CHECK_CLIENT_REQUEST;
|
||||
if (!true) {
|
||||
writeError(0, "");
|
||||
server_state = NegotiationServerTask.State.ERROR;
|
||||
// ToDo: Error handling
|
||||
}
|
||||
|
||||
// send offer
|
||||
NegotiationOffer offer = new NegotiationOffer(1, 100, 0);
|
||||
String offerString = gson.toJson(offer);
|
||||
|
||||
|
||||
sendLine(offerString);
|
||||
|
||||
// WAIT_FOR_ANSWER
|
||||
server_state = NegotiationServerTask.State.WAIT_FOR_ANSWER;
|
||||
String answerString = getLine();
|
||||
|
||||
// Parse the answer
|
||||
NegotiationOfferAnswer answer = gson.fromJson(answerString, NegotiationOfferAnswer.class);
|
||||
PeerStore.getInstance().setLatestOfferAnswer(macAddress, answer);
|
||||
|
||||
// CHECK_ANSWER
|
||||
server_state = NegotiationServerTask.State.CHECK_ANSWER;
|
||||
|
||||
if (!answer.isAgreeToConditions()) {
|
||||
writeError(0, "Client does not agree to conditions");
|
||||
server_state = NegotiationServerTask.State.ERROR;
|
||||
return false;
|
||||
// ToDo: Error handling
|
||||
}
|
||||
|
||||
// CHECK_ITP
|
||||
// server_state = NegotiationServerTask.State.CHECK_ITP;
|
||||
// if (!true) {
|
||||
// writeError(0, "");
|
||||
// server_state = NegotiationServerTask.State.ERROR;
|
||||
// // ToDo: Error handling
|
||||
// }
|
||||
|
||||
// GENERATE_PASSWORD
|
||||
server_state = NegotiationServerTask.State.GENERATE_PASSWORD;
|
||||
String password = "123456789";
|
||||
String hotspotName = "Iotify-123";
|
||||
|
||||
// send password and hotspot name
|
||||
NegotiationFinalization finalization = new NegotiationFinalization(hotspotName, password,
|
||||
"Address", 0, 0, "");
|
||||
String finalizationString = gson.toJson(finalization);
|
||||
|
||||
sendLine(finalizationString);
|
||||
|
||||
// WAIT_FOR_OK
|
||||
server_state = NegotiationServerTask.State.WAIT_FOR_OK;
|
||||
String ok = getLine();
|
||||
|
||||
// CREATE_HOTSPOT
|
||||
server_state = NegotiationServerTask.State.CREATE_HOTSPOT;
|
||||
|
||||
// now close the socket and leave
|
||||
server_state = NegotiationServerTask.State.SUCCESS;
|
||||
|
||||
socket.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Void... values) {}
|
||||
|
||||
public enum State {
|
||||
INITIAL,
|
||||
WAIT_FOR_OFFER,
|
||||
CHECK_OFFER,
|
||||
WAIT_FOR_PASSWORD,
|
||||
SUCCESS,
|
||||
ERROR;
|
||||
}
|
||||
}
|
||||
@ -1,311 +0,0 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import com.flashwifi.wifip2p.datastore.PeerStore;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationFinalization;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOffer;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOfferAnswer;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
|
||||
|
||||
public class NegotiationServerTask extends AsyncTask<String, Void, String> {
|
||||
|
||||
private static final String TAG = "NegServerTask";
|
||||
|
||||
private boolean running = true;
|
||||
private ServerSocket serverSocket;
|
||||
private Socket socket;
|
||||
private State server_state;
|
||||
private NegotiationClientTask.State client_state;
|
||||
|
||||
private boolean isClient = false;
|
||||
|
||||
BufferedReader in;
|
||||
PrintWriter out;
|
||||
|
||||
public String getLine() {
|
||||
String response;
|
||||
try {
|
||||
response = in.readLine();
|
||||
} catch (IOException ex) {
|
||||
response = "Error: " + ex;
|
||||
}
|
||||
Log.d(TAG, "getLine: " + response);
|
||||
return response;
|
||||
}
|
||||
|
||||
private void sendLine(String line) {
|
||||
out.println(line);
|
||||
}
|
||||
|
||||
public void writeError(int code, String msg) {
|
||||
sendLine(String.format("err_code: %s msg: %s", Integer.toString(code), msg));
|
||||
}
|
||||
|
||||
private boolean runServer(boolean isClient, String macAddress) {
|
||||
boolean success = false;
|
||||
|
||||
try {
|
||||
serverSocket = new ServerSocket(9898);
|
||||
// set the timeout for the negotiation protocol to 1 second
|
||||
// ToDo: make this a variable
|
||||
int timeout = 1000;
|
||||
|
||||
serverSocket.setSoTimeout(timeout);
|
||||
server_state = State.INITIAL;
|
||||
Log.d(TAG, "doInBackground: Server is waiting for connection");
|
||||
socket = serverSocket.accept();
|
||||
socket.setSoTimeout(timeout);
|
||||
|
||||
// get ip and port of client
|
||||
InetAddress addr = socket.getInetAddress();
|
||||
int port = socket.getPort();
|
||||
|
||||
// ToDo: clear this problem
|
||||
macAddress = addr.getHostAddress();
|
||||
|
||||
// set up the stream reader and writer
|
||||
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
out = new PrintWriter(socket.getOutputStream(), true);
|
||||
|
||||
// WAIT FOR CLIENT
|
||||
server_state = State.WAIT_FOR_CLIENT;
|
||||
String hello = getLine();
|
||||
|
||||
// Check: Is the peer in the same role as we are?
|
||||
// server and server or client and client MAKES NO SENSE
|
||||
// we have to check this because we can't control it
|
||||
if (hello.contains("SERVER") && !isClient || hello.contains("CLIENT") && isClient) {
|
||||
Log.d(TAG, "doInBackground: Pairing roles are broken.");
|
||||
server_state = State.ERROR;
|
||||
socket.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we are the server
|
||||
if (!isClient) {
|
||||
success = runServerProtocol(macAddress);
|
||||
} else {
|
||||
// we are the client
|
||||
success = runClientProtocol(macAddress);
|
||||
}
|
||||
} catch (SocketTimeoutException ste) {
|
||||
System.out.println("### Timed out after 1 seconds");
|
||||
} catch (IOException e) {
|
||||
Log.d("", e.getMessage());
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (serverSocket != null) {
|
||||
try {
|
||||
serverSocket.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(String... params) {
|
||||
String return_string = null;
|
||||
|
||||
String isClientString = params[0];
|
||||
if (isClientString.equals("True")) {
|
||||
isClient = true;
|
||||
}
|
||||
|
||||
String macAddress = params[1];
|
||||
|
||||
boolean success = false;
|
||||
|
||||
while (!success) {
|
||||
success = runServer(isClient, macAddress);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return return_string;
|
||||
}
|
||||
|
||||
|
||||
private void closeConnection() throws IOException {
|
||||
socket.close();
|
||||
}
|
||||
|
||||
private boolean runClientProtocol(String macAddress) throws IOException {
|
||||
|
||||
Gson gson = new Gson();
|
||||
|
||||
// WAIT FOR OFFER
|
||||
client_state = NegotiationClientTask.State.WAIT_FOR_OFFER;
|
||||
|
||||
String offerString = getLine();
|
||||
if (offerString == null) {
|
||||
closeConnection();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// CHECK OFFER
|
||||
client_state = NegotiationClientTask.State.CHECK_OFFER;
|
||||
|
||||
// Get offer
|
||||
|
||||
NegotiationOffer offer = gson.fromJson(offerString, NegotiationOffer.class);
|
||||
// Write offer to the PeerStore
|
||||
PeerStore.getInstance().setLatestOffer(macAddress, offer);
|
||||
|
||||
// ToDo: implement accept or deny logic
|
||||
if (!true) {
|
||||
client_state = NegotiationClientTask.State.ERROR;
|
||||
writeError(1, "Offer not acceptable");
|
||||
// ToDo: Error handling
|
||||
return false;
|
||||
}
|
||||
|
||||
// SEND NegotiationAnswer
|
||||
NegotiationOfferAnswer answer = new NegotiationOfferAnswer(true, 10);
|
||||
String answerString = gson.toJson(answer);
|
||||
sendLine(answerString);
|
||||
|
||||
// WAIT FOR PASSWORD and hostname
|
||||
client_state = NegotiationClientTask.State.WAIT_FOR_PASSWORD;
|
||||
String finalizationString = getLine();
|
||||
|
||||
if (finalizationString == null) {
|
||||
closeConnection();
|
||||
return false;
|
||||
}
|
||||
|
||||
NegotiationFinalization finalization = gson.fromJson(finalizationString, NegotiationFinalization.class);
|
||||
// Write offer to the PeerStore
|
||||
PeerStore.getInstance().setLatestFinalization(macAddress, finalization);
|
||||
|
||||
|
||||
// Send OK
|
||||
sendLine("OK from Client");
|
||||
client_state = NegotiationClientTask.State.SUCCESS;
|
||||
|
||||
socket.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean runServerProtocol(String macAddress) throws IOException {
|
||||
// Json serializer
|
||||
Gson gson = new GsonBuilder().create();
|
||||
|
||||
|
||||
// CHECK_CLIENT_REQUEST
|
||||
server_state = NegotiationServerTask.State.CHECK_CLIENT_REQUEST;
|
||||
if (!true) {
|
||||
writeError(0, "");
|
||||
server_state = NegotiationServerTask.State.ERROR;
|
||||
// ToDo: Error handling
|
||||
}
|
||||
|
||||
// send offer
|
||||
NegotiationOffer offer = new NegotiationOffer(1, 100, 0);
|
||||
String offerString = gson.toJson(offer);
|
||||
|
||||
|
||||
sendLine(offerString);
|
||||
|
||||
// WAIT_FOR_ANSWER
|
||||
server_state = NegotiationServerTask.State.WAIT_FOR_ANSWER;
|
||||
String answerString = getLine();
|
||||
|
||||
// Parse the answer
|
||||
NegotiationOfferAnswer answer = gson.fromJson(answerString, NegotiationOfferAnswer.class);
|
||||
PeerStore.getInstance().setLatestOfferAnswer(macAddress, answer);
|
||||
|
||||
// CHECK_ANSWER
|
||||
server_state = NegotiationServerTask.State.CHECK_ANSWER;
|
||||
|
||||
if (!answer.isAgreeToConditions()) {
|
||||
writeError(0, "Client does not agree to conditions");
|
||||
server_state = NegotiationServerTask.State.ERROR;
|
||||
return false;
|
||||
// ToDo: Error handling
|
||||
}
|
||||
|
||||
// CHECK_ITP
|
||||
// server_state = NegotiationServerTask.State.CHECK_ITP;
|
||||
// if (!true) {
|
||||
// writeError(0, "");
|
||||
// server_state = NegotiationServerTask.State.ERROR;
|
||||
// // ToDo: Error handling
|
||||
// }
|
||||
|
||||
// GENERATE_PASSWORD
|
||||
server_state = NegotiationServerTask.State.GENERATE_PASSWORD;
|
||||
String password = "123456789";
|
||||
String hotspotName = "Iotify-123";
|
||||
|
||||
// send password and hotspot name
|
||||
NegotiationFinalization finalization = new NegotiationFinalization(hotspotName, password,
|
||||
"Address", 0, 0, "");
|
||||
String finalizationString = gson.toJson(finalization);
|
||||
|
||||
sendLine(finalizationString);
|
||||
|
||||
// WAIT_FOR_OK
|
||||
server_state = NegotiationServerTask.State.WAIT_FOR_OK;
|
||||
String ok = getLine();
|
||||
|
||||
// CREATE_HOTSPOT
|
||||
server_state = NegotiationServerTask.State.CREATE_HOTSPOT;
|
||||
|
||||
// now close the socket and leave
|
||||
server_state = NegotiationServerTask.State.SUCCESS;
|
||||
|
||||
socket.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Void... values) {}
|
||||
|
||||
public enum State {
|
||||
INITIAL,
|
||||
WAIT_FOR_CLIENT,
|
||||
CHECK_CLIENT_REQUEST,
|
||||
WAIT_FOR_ANSWER,
|
||||
CHECK_ANSWER,
|
||||
CHECK_ITP,
|
||||
GENERATE_PASSWORD,
|
||||
WAIT_FOR_OK,
|
||||
CREATE_HOTSPOT,
|
||||
SUCCESS,
|
||||
ERROR;
|
||||
}
|
||||
}
|
||||
@ -11,11 +11,7 @@ import android.net.NetworkInfo;
|
||||
import android.net.wifi.p2p.WifiP2pInfo;
|
||||
import android.net.wifi.p2p.WifiP2pManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
@ -33,6 +29,8 @@ import com.flashwifi.wifip2p.datastore.PeerStore;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.flashwifi.wifip2p.broadcast.WiFiDirectBroadcastService;
|
||||
|
||||
/**
|
||||
* Fragment that appears in the "content_frame", shows a planet
|
||||
*/
|
||||
@ -222,10 +220,10 @@ public class SearchFragment extends Fragment {
|
||||
startNegotiationProtocol(address);
|
||||
|
||||
|
||||
Intent intent = new Intent(getActivity(), ChatActivity.class);
|
||||
/*Intent intent = new Intent(getActivity(), ChatActivity.class);
|
||||
intent.putExtra("address", address);
|
||||
intent.putExtra("name", name);
|
||||
startActivity(intent);
|
||||
startActivity(intent);*/
|
||||
}
|
||||
|
||||
public void onRefreshButtonClick() {
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
public class ServerTask extends AsyncTask<String, Void, String> {
|
||||
|
||||
private boolean running = true;
|
||||
|
||||
@Override
|
||||
protected String doInBackground(String... params) {
|
||||
try {
|
||||
|
||||
String msg_received = null;
|
||||
|
||||
while (running) {
|
||||
ServerSocket serverSocket = new ServerSocket(9999);
|
||||
Socket client = serverSocket.accept();
|
||||
Log.d("ServerTask", "doInBackground: openend");
|
||||
DataInputStream DIS = new DataInputStream(client.getInputStream());
|
||||
msg_received = DIS.readUTF();
|
||||
Log.d(">>>>>", msg_received);
|
||||
serverSocket.close();
|
||||
}
|
||||
|
||||
return msg_received;
|
||||
} catch (IOException e) {
|
||||
Log.d("", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Void... values) {}
|
||||
}
|
||||
@ -1,9 +1,7 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
package com.flashwifi.wifip2p.accesspoint;
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.wifi.p2p.WifiP2pManager;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
package com.flashwifi.wifip2p.accesspoint;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
@ -1,4 +1,4 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
package com.flashwifi.wifip2p.broadcast;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
@ -1,7 +1,4 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
package com.flashwifi.wifip2p.broadcast;
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
@ -15,9 +12,9 @@ import android.net.wifi.p2p.WifiP2pInfo;
|
||||
import android.net.wifi.p2p.WifiP2pManager;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
@ -28,8 +25,6 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
|
||||
// Binder given to clients
|
||||
private final IBinder mBinder = new LocalBinder();
|
||||
// Random number generator
|
||||
private final Random mGenerator = new Random();
|
||||
|
||||
private boolean setup = false;
|
||||
|
||||
@ -47,7 +42,6 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
ArrayList<String> receivedMessages = new ArrayList<>();
|
||||
|
||||
// socket stuff
|
||||
NegotiationServerTask negotiationServerTask;
|
||||
boolean serverRuns;
|
||||
|
||||
private String currentDeviceConnected = null;
|
||||
@ -60,18 +54,16 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
//negotiationServerTask = new NegotiationServerTask();
|
||||
//negotiationServerTask.execute();
|
||||
String isClientString = (isClient) ? "True" : "False";
|
||||
new NegotiationServerTask().execute(isClientString, macAddress);
|
||||
// ToDo: rewire this
|
||||
// new NegotiationServerTask().execute(isClientString, macAddress);
|
||||
}
|
||||
|
||||
public void startNegotiationClient(InetAddress address, boolean isClient, String macAddress) {
|
||||
Log.d("", "startSocketClient: ");
|
||||
String isClientString = (isClient) ? "True" : "False";
|
||||
String ipaddr = address.getHostAddress();
|
||||
new NegotiationClientTask().execute(isClientString, ipaddr, macAddress);
|
||||
}
|
||||
|
||||
public void sendMessageToSocketServer(InetAddress address, String message) {
|
||||
new ClientTask().execute(address.getHostAddress(), message);
|
||||
// ToDo: use the Negotiator here
|
||||
// new NegotiationClientTask().execute(isClientString, ipaddr, macAddress);
|
||||
}
|
||||
|
||||
public WifiP2pInfo getP2p_info() {
|
||||
@ -136,7 +128,7 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
* runs in the same process as its clients, we don't need to deal with IPC.
|
||||
*/
|
||||
public class LocalBinder extends Binder {
|
||||
WiFiDirectBroadcastService getService() {
|
||||
public WiFiDirectBroadcastService getService() {
|
||||
// Return this instance of LocalService so clients can call public methods
|
||||
return WiFiDirectBroadcastService.this;
|
||||
}
|
||||
@ -65,7 +65,15 @@ public class PeerInformation {
|
||||
this.latestFinalization = latestFinalization;
|
||||
}
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public NegotiationFinalization getLatestFinalization() {
|
||||
return latestFinalization;
|
||||
}
|
||||
|
||||
public void setIPAddress(String IPAddress) {
|
||||
this.ipAddress = IPAddress;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.flashwifi.wifip2p.datastore;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.wifi.p2p.WifiP2pDevice;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -8,6 +9,7 @@ import android.widget.ArrayAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.flashwifi.wifip2p.R;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOffer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -38,15 +40,30 @@ public class PeerListAdapter extends ArrayAdapter<PeerInformation> {
|
||||
TextView tt1 = (TextView) v.findViewById(R.id.deviceName);
|
||||
TextView tt2 = (TextView) v.findViewById(R.id.categoryId);
|
||||
TextView tt3 = (TextView) v.findViewById(R.id.description);
|
||||
TextView tt4 = (TextView) v.findViewById(R.id.ipAddr);
|
||||
TextView tt5 = (TextView) v.findViewById(R.id.iotaPrice);
|
||||
|
||||
if (tt1 != null) {
|
||||
tt1.setText(p.getWifiP2pDevice().deviceName);
|
||||
WifiP2pDevice device = p.getWifiP2pDevice();
|
||||
if (device != null) {
|
||||
if (tt1 != null) {
|
||||
tt1.setText(p.getWifiP2pDevice().deviceName);
|
||||
}
|
||||
|
||||
if (tt2 != null) {
|
||||
tt2.setText(p.getWifiP2pDevice().deviceAddress);
|
||||
}
|
||||
}
|
||||
|
||||
if (tt2 != null) {
|
||||
tt2.setText(p.getWifiP2pDevice().deviceAddress);
|
||||
NegotiationOffer offer = p.getLatestNegotiationOffer();
|
||||
if (offer != null) {
|
||||
tt5.setText(Integer.toString(offer.getIotaPerMegabyte()));
|
||||
}
|
||||
|
||||
if (p.getIpAddress() != null) {
|
||||
tt4.setText(p.getIpAddress());
|
||||
}
|
||||
|
||||
|
||||
if (tt3 != null)
|
||||
tt3.setText(String.format("%s", Integer.toString(p.getAge())));
|
||||
}
|
||||
|
||||
@ -91,4 +91,8 @@ public class PeerStore {
|
||||
public void setLatestFinalization(String macAddress, NegotiationFinalization finalization) {
|
||||
getOrCreatePeer(macAddress).setLatestFinalization(finalization);
|
||||
}
|
||||
|
||||
public void setIPAddress(String macAddress, InetAddress IPAddress) {
|
||||
getOrCreatePeer(macAddress).setIPAddress(IPAddress.getHostAddress());
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,292 @@
|
||||
package com.flashwifi.wifip2p.negotiation;
|
||||
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.flashwifi.wifip2p.datastore.PeerStore;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationFinalization;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOffer;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOfferAnswer;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
|
||||
public class Negotiator {
|
||||
private static final String TAG = "Negotiator";
|
||||
private static final int PORT = 9898;
|
||||
private static final int timeoutMillis = 1000;
|
||||
|
||||
private SocketWrapper socketWrapper;
|
||||
|
||||
private HotspotState hotspot_state;
|
||||
private ConsumerState consumer_state;
|
||||
|
||||
// client as in client-server
|
||||
private boolean isClient;
|
||||
// consumer as in consumer-hotspot
|
||||
private boolean isConsumer;
|
||||
|
||||
private Gson gson;
|
||||
|
||||
public enum ConsumerState {
|
||||
INITIAL,
|
||||
WAIT_FOR_OFFER,
|
||||
CHECK_OFFER,
|
||||
WAIT_FOR_PASSWORD,
|
||||
SUCCESS,
|
||||
ERROR
|
||||
}
|
||||
|
||||
public enum HotspotState {
|
||||
INITIAL,
|
||||
WAIT_FOR_CLIENT,
|
||||
CHECK_CLIENT_REQUEST,
|
||||
WAIT_FOR_ANSWER,
|
||||
CHECK_ANSWER,
|
||||
CHECK_ITP,
|
||||
GENERATE_PASSWORD,
|
||||
WAIT_FOR_OK,
|
||||
CREATE_HOTSPOT,
|
||||
SUCCESS,
|
||||
ERROR
|
||||
}
|
||||
|
||||
public Negotiator(boolean isConsumer) {
|
||||
this.isConsumer = isConsumer;
|
||||
gson = new GsonBuilder().create();
|
||||
}
|
||||
|
||||
public boolean workAsClient(String serverIPAddress) {
|
||||
this.isClient = true;
|
||||
|
||||
boolean success = false;
|
||||
Socket socket = null;
|
||||
|
||||
try {
|
||||
// create client socket that connects to server
|
||||
socket = new Socket(serverIPAddress, PORT);
|
||||
socket.setSoTimeout(timeoutMillis);
|
||||
Log.d(TAG, "workAsClient: client socket created");
|
||||
|
||||
// wrap the socket
|
||||
socketWrapper = new SocketWrapper(socket);
|
||||
|
||||
// send Client Request
|
||||
String hello = isConsumer ? "HELLO I AM CLIENT" : "HELLO I AM SERVER";
|
||||
socketWrapper.sendLine(hello);
|
||||
|
||||
// Whether we want to provide a hotspot or use one
|
||||
if (isConsumer) {
|
||||
success = runConsumerProtocol(serverIPAddress);
|
||||
} else {
|
||||
success = runHotspotProtocol(serverIPAddress);
|
||||
}
|
||||
} catch (SocketTimeoutException ste) {
|
||||
Log.d(TAG, "workAsServer: ### Timed out after 1 seconds");
|
||||
} catch (IOException e) {
|
||||
Log.d("", e.getMessage());
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public boolean workAsServer() {
|
||||
// this device is the socket server
|
||||
this.isClient = false;
|
||||
|
||||
boolean success = false;
|
||||
ServerSocket serverSocket = null;
|
||||
Socket socket = null;
|
||||
|
||||
try {
|
||||
// use the port to start
|
||||
serverSocket = new ServerSocket(PORT);
|
||||
serverSocket.setSoTimeout(timeoutMillis);
|
||||
Log.d(TAG, "doInBackground: Server is waiting for connection");
|
||||
|
||||
// accept one connection
|
||||
socket = serverSocket.accept();
|
||||
socket.setSoTimeout(timeoutMillis);
|
||||
|
||||
// wrap the socket
|
||||
socketWrapper = new SocketWrapper(socket);
|
||||
|
||||
// WAIT FOR CLIENT
|
||||
String hello = socketWrapper.getLine();
|
||||
|
||||
// Check: Is the peer in the same role as we are
|
||||
// server and server or client and client MAKES NO SENSE
|
||||
if (hello.contains("SERVER") && !isClient || hello.contains("CLIENT") && isClient) {
|
||||
error(1, "Pairing roles are broken");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Whether we want to provide a hotspot or use one
|
||||
if (isConsumer) {
|
||||
success = runConsumerProtocol(socketWrapper.getClientAddress().getHostAddress());
|
||||
} else {
|
||||
success = runHotspotProtocol(socketWrapper.getClientAddress().getHostAddress());
|
||||
}
|
||||
} catch (SocketTimeoutException ste) {
|
||||
Log.d(TAG, "workAsServer: ### Timed out after 1 seconds");
|
||||
} catch (IOException e) {
|
||||
Log.d("", e.getMessage());
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (serverSocket != null) {
|
||||
try {
|
||||
serverSocket.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
private boolean runConsumerProtocol(String ipAddress) throws IOException {
|
||||
consumer_state = ConsumerState.WAIT_FOR_OFFER;
|
||||
|
||||
// RECEIVE OFFER
|
||||
String offerString = socketWrapper.getLine();
|
||||
if (offerString == null) {
|
||||
error(2, "No offer received");
|
||||
return false;
|
||||
}
|
||||
|
||||
// CHECK OFFER
|
||||
consumer_state = ConsumerState.CHECK_OFFER;
|
||||
NegotiationOffer offer = gson.fromJson(offerString, NegotiationOffer.class);
|
||||
// Write offer to the PeerStore
|
||||
PeerStore.getInstance().setLatestOffer(ipAddress, offer);
|
||||
|
||||
// ToDo: implement accept or deny logic
|
||||
if (!true) {
|
||||
error(3, "Offer not acceptable");
|
||||
return false;
|
||||
}
|
||||
|
||||
// SEND NegotiationAnswer
|
||||
// ToDo: where shall the input come from?
|
||||
NegotiationOfferAnswer answer = new NegotiationOfferAnswer(true, 10);
|
||||
String answerString = gson.toJson(answer);
|
||||
socketWrapper.sendLine(answerString);
|
||||
|
||||
// WAIT FOR PASSWORD and hostname
|
||||
consumer_state = ConsumerState.WAIT_FOR_PASSWORD;
|
||||
String finalizationString = socketWrapper.getLine();
|
||||
|
||||
if (finalizationString == null) {
|
||||
error(4, "No finalization received");
|
||||
return false;
|
||||
}
|
||||
|
||||
NegotiationFinalization finalization = gson.fromJson(finalizationString, NegotiationFinalization.class);
|
||||
// Write offer to the PeerStore
|
||||
PeerStore.getInstance().setLatestFinalization(ipAddress, finalization);
|
||||
|
||||
|
||||
// Send OK
|
||||
socketWrapper.sendLine("OK from Client");
|
||||
consumer_state = ConsumerState.SUCCESS;
|
||||
|
||||
// End
|
||||
socketWrapper.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean runHotspotProtocol(String ipAddress) throws IOException {
|
||||
// CHECK_CLIENT_REQUEST
|
||||
hotspot_state = HotspotState.CHECK_CLIENT_REQUEST;
|
||||
|
||||
// send offer
|
||||
NegotiationOffer offer = new NegotiationOffer(1, 100, 0);
|
||||
String offerString = gson.toJson(offer);
|
||||
socketWrapper.sendLine(offerString);
|
||||
|
||||
// WAIT_FOR_ANSWER
|
||||
hotspot_state = HotspotState.WAIT_FOR_ANSWER;
|
||||
String answerString = socketWrapper.getLine();
|
||||
|
||||
// Parse the answer
|
||||
NegotiationOfferAnswer answer = gson.fromJson(answerString, NegotiationOfferAnswer.class);
|
||||
PeerStore.getInstance().setLatestOfferAnswer(ipAddress, answer);
|
||||
|
||||
// CHECK_ANSWER
|
||||
hotspot_state = HotspotState.CHECK_ANSWER;
|
||||
|
||||
if (!answer.isAgreeToConditions()) {
|
||||
error(5, "Client does not agree to conditions");
|
||||
return false;
|
||||
}
|
||||
|
||||
// CHECK_ITP
|
||||
// server_state = NegotiationServerTask.State.CHECK_ITP;
|
||||
// if (!true) {
|
||||
// writeError(0, "");
|
||||
// server_state = NegotiationServerTask.State.ERROR;
|
||||
// // ToDo: Error handling
|
||||
// }
|
||||
|
||||
// GENERATE_PASSWORD
|
||||
// ToDo: Don't mock this
|
||||
hotspot_state = HotspotState.GENERATE_PASSWORD;
|
||||
String password = "123456789";
|
||||
String hotspotName = "Iotify-123";
|
||||
|
||||
// send password and hotspot name
|
||||
NegotiationFinalization finalization = new NegotiationFinalization(hotspotName, password,
|
||||
"Address", 0, 0, "");
|
||||
String finalizationString = gson.toJson(finalization);
|
||||
|
||||
socketWrapper.sendLine(finalizationString);
|
||||
|
||||
// WAIT_FOR_OK
|
||||
hotspot_state = HotspotState.WAIT_FOR_OK;
|
||||
String ok = socketWrapper.getLine();
|
||||
|
||||
// CREATE_HOTSPOT
|
||||
hotspot_state = HotspotState.CREATE_HOTSPOT;
|
||||
|
||||
// now close the socket and leave
|
||||
hotspot_state = HotspotState.SUCCESS;
|
||||
|
||||
socketWrapper.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// HELPER METHODS BELOW
|
||||
// ------------------------
|
||||
|
||||
private void error(int code, String msg) throws IOException {
|
||||
Log.d(TAG, "error: " + msg);
|
||||
if (isConsumer) {
|
||||
consumer_state = ConsumerState.ERROR;
|
||||
} else {
|
||||
hotspot_state = HotspotState.ERROR;
|
||||
}
|
||||
socketWrapper.close();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package com.flashwifi.wifip2p.negotiation;
|
||||
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
public class SocketWrapper {
|
||||
private static final String TAG = "SocketWrapper";
|
||||
private Socket socket;
|
||||
private BufferedReader in;
|
||||
private PrintWriter out;
|
||||
|
||||
public SocketWrapper(Socket socket) throws IOException {
|
||||
this.socket = socket;
|
||||
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
out = new PrintWriter(socket.getOutputStream(), true);
|
||||
}
|
||||
|
||||
public String getLine() {
|
||||
String response;
|
||||
try {
|
||||
response = in.readLine();
|
||||
} catch (IOException ex) {
|
||||
response = "Error: " + ex;
|
||||
}
|
||||
Log.d(TAG, "getLine: " + response);
|
||||
return response;
|
||||
}
|
||||
|
||||
public void sendLine(String line) {
|
||||
out.println(line);
|
||||
Log.d(TAG, "sendLine: " + line);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
socket.close();
|
||||
}
|
||||
|
||||
public InetAddress getClientAddress() {
|
||||
return socket.getInetAddress();
|
||||
}
|
||||
}
|
||||
@ -13,4 +13,20 @@ public class NegotiationOffer {
|
||||
this.maxMinutes = maxMinutes;
|
||||
this.iotaPerMegabyte = iotaPerMegabyte;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getMinMinutes() {
|
||||
return minMinutes;
|
||||
}
|
||||
|
||||
public int getMaxMinutes() {
|
||||
return maxMinutes;
|
||||
}
|
||||
|
||||
public int getIotaPerMegabyte() {
|
||||
return iotaPerMegabyte;
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,17 @@
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.NoActionBar.PopupOverlay" />
|
||||
|
||||
<!-- <ToggleButton
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="right"
|
||||
android:textOn="WiFi P2P"
|
||||
android:textOff="WiFi P2P"
|
||||
android:text="WiFi P2P"
|
||||
android:visibility="invisible"
|
||||
android:id="@+id/wifip2pToggle"/>-->
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<include layout="@layout/content_main" />
|
||||
|
||||
@ -39,5 +39,27 @@
|
||||
android:text="description"
|
||||
android:height="20sp" />
|
||||
</TableRow>
|
||||
<TableRow android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent">
|
||||
|
||||
<TextView android:textColor="#000000"
|
||||
android:id="@+id/ipAddr"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ipAddr"
|
||||
android:layout_weight="1"
|
||||
android:height="20sp" />
|
||||
|
||||
<TextView android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:textColor="#000000"
|
||||
android:gravity="right"
|
||||
android:id="@+id/iotaPrice"
|
||||
android:text="iotaPrice"
|
||||
android:height="20sp" />
|
||||
|
||||
</TableRow>
|
||||
|
||||
|
||||
</TableLayout>
|
||||
Loading…
Reference in New Issue
Block a user