diff --git a/app/src/main/java/com/flashwifi/wifip2p/ChatActivity.java b/app/src/main/java/com/flashwifi/wifip2p/ChatActivity.java index d2749eb..2fe9a33 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/ChatActivity.java +++ b/app/src/main/java/com/flashwifi/wifip2p/ChatActivity.java @@ -103,22 +103,7 @@ public class ChatActivity extends AppCompatActivity { - private void connectToPeer(String address) { - if (mBound) { - mService.connect(address, new WifiP2pManager.ActionListener() { - @Override - public void onSuccess() { - Toast.makeText(getApplicationContext(), "Connected to peer", Toast.LENGTH_SHORT).show(); - } - @Override - public void onFailure(int reason) { - Toast.makeText(getApplicationContext(), "Error connecting to peer", Toast.LENGTH_SHORT).show(); - } - }); - } else { - Toast.makeText(getApplicationContext(), "Service not available", Toast.LENGTH_SHORT).show(); - } - } + private void initUI() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); diff --git a/app/src/main/java/com/flashwifi/wifip2p/SearchFragment.java b/app/src/main/java/com/flashwifi/wifip2p/SearchFragment.java index 96ffe4a..73314d0 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/SearchFragment.java +++ b/app/src/main/java/com/flashwifi/wifip2p/SearchFragment.java @@ -21,6 +21,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ListView; +import android.widget.Toast; import com.flashwifi.wifip2p.datastore.PeerInformation; import com.flashwifi.wifip2p.datastore.PeerListAdapter; @@ -45,6 +46,9 @@ public class SearchFragment extends Fragment { ArrayList arrayList; PeerListAdapter peerListAdapter; + View view; + private boolean busy = false; + public SearchFragment() { // Empty constructor required for fragment subclasses @@ -89,11 +93,15 @@ public class SearchFragment extends Fragment { return f; } - private void updateUi(Intent intent) { + private void updateList() { peerListAdapter.notifyDataSetInvalidated(); peerListAdapter.clear(); peerListAdapter.addAll(PeerStore.getInstance().getPeerArrayList()); peerListAdapter.notifyDataSetChanged(); + } + + private void updateUi(Intent intent) { + updateList(); String what = intent.getStringExtra("what"); Log.d(">>>>>>>>>>>>", "updateUi: " + what); @@ -176,6 +184,8 @@ public class SearchFragment extends Fragment { Intent intent = new Intent(getActivity(), WiFiDirectBroadcastService.class); getActivity().bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + view = getActivity().findViewById(R.id.main_view); + initUI(); } @@ -205,20 +215,39 @@ public class SearchFragment extends Fragment { listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { - PeerInformation peer = PeerStore.getInstance().getPeerArrayList().get(i); + if (!busy) { + busy = true; + PeerInformation peer = PeerStore.getInstance().getPeerArrayList().get(i); - String address = peer.getWifiP2pDevice().deviceAddress; - String name = peer.getWifiP2pDevice().deviceName; + peer.setSelected(true); + updateList(); - startChat(address, name); + String address = peer.getWifiP2pDevice().deviceAddress; + String name = peer.getWifiP2pDevice().deviceName; + + startChat(address, name); + } else { + Toast.makeText(view.getContext(), "Busy", Toast.LENGTH_SHORT).show(); + } } }); } - public void startChat(String address, String name) { - // start the socket for the negotiation - startNegotiationProtocol(address); - + public void startChat(final String address, String name) { + mService.connect(address, new WifiP2pManager.ActionListener() { + @Override + public void onSuccess() { + Toast.makeText(view.getContext(), "Connected to peer", Toast.LENGTH_SHORT).show(); + // start the protocol + startNegotiationProtocol(address); + busy = false; + } + @Override + public void onFailure(int reason) { + Toast.makeText(view.getContext(), "Error connecting to peer", Toast.LENGTH_SHORT).show(); + busy = false; + } + }); /*Intent intent = new Intent(getActivity(), ChatActivity.class); intent.putExtra("address", address); @@ -227,7 +256,7 @@ public class SearchFragment extends Fragment { } public void onRefreshButtonClick() { - final View view = getActivity().findViewById(R.id.main_view); + if (mBound) { mService.getPeerList(new WifiP2pManager.ActionListener() { @Override diff --git a/app/src/main/java/com/flashwifi/wifip2p/broadcast/WiFiDirectBroadcastService.java b/app/src/main/java/com/flashwifi/wifip2p/broadcast/WiFiDirectBroadcastService.java index 4d30efc..dbe4301 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/broadcast/WiFiDirectBroadcastService.java +++ b/app/src/main/java/com/flashwifi/wifip2p/broadcast/WiFiDirectBroadcastService.java @@ -5,19 +5,28 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.NetworkInfo; +import android.net.wifi.WifiInfo; import android.net.wifi.p2p.WifiP2pConfig; 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.AsyncTask; import android.os.Binder; import android.os.IBinder; import android.util.Log; +import android.widget.Toast; +import com.flashwifi.wifip2p.WalletAddressAndBalanceChecker; +import com.flashwifi.wifip2p.negotiation.Negotiator; + import java.lang.reflect.Method; import java.net.InetAddress; +import java.net.NetworkInterface; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Random; public class WiFiDirectBroadcastService extends Service { @@ -49,21 +58,74 @@ public class WiFiDirectBroadcastService extends Service { // discovery mode private boolean discoveryModeActive = false; - public void startNegotiationServer(boolean isClient, String macAddress) { - Log.d("", "startSocketServer: "); - //negotiationServerTask = new NegotiationServerTask(); - //negotiationServerTask.execute(); - String isClientString = (isClient) ? "True" : "False"; - // ToDo: rewire this - // new NegotiationServerTask().execute(isClientString, macAddress); + public String getWFDMacAddress(){ + try { + List interfaces = Collections.list(NetworkInterface.getNetworkInterfaces()); + for (NetworkInterface ntwInterface : interfaces) { + + if (ntwInterface.getName().equalsIgnoreCase("p2p0")) { + byte[] byteMac = ntwInterface.getHardwareAddress(); + if (byteMac==null){ + return null; + } + StringBuilder strBuilder = new StringBuilder(); + for (int i=0; i0){ + strBuilder.deleteCharAt(strBuilder.length()-1); + } + + return strBuilder.toString(); + } + + } + } catch (Exception e) { + Log.d(TAG, e.getMessage()); + } + return null; } - public void startNegotiationClient(InetAddress address, boolean isClient, String macAddress) { - Log.d("", "startSocketClient: "); - String isClientString = (isClient) ? "True" : "False"; - String ipaddr = address.getHostAddress(); - // ToDo: use the Negotiator here - // new NegotiationClientTask().execute(isClientString, ipaddr, macAddress); + public void startNegotiationServer(final boolean isClient, String macAddress) { + AsyncTask.execute(new Runnable() { + @Override + public void run() { + Negotiator negotiator = new Negotiator(isClient, getWFDMacAddress()); + // ToDo: run as long as this group is connected + while (true) { + negotiator.workAsServer(); + deletePersistentGroups(); + sendUpdateUIBroadcast(); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }); + } + + public void startNegotiationClient(final InetAddress address, final boolean isClient, String macAddress) { + AsyncTask.execute(new Runnable() { + @Override + public void run() { + Negotiator negotiator = new Negotiator(isClient, getWFDMacAddress()); + // ToDo: run as long as this group is connected + while (true) { + negotiator.workAsClient(address.getHostAddress()); + deletePersistentGroups(); + sendUpdateUIBroadcast(); + + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }); } public WifiP2pInfo getP2p_info() { diff --git a/app/src/main/java/com/flashwifi/wifip2p/datastore/PeerInformation.java b/app/src/main/java/com/flashwifi/wifip2p/datastore/PeerInformation.java index 623d257..e25caf5 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/datastore/PeerInformation.java +++ b/app/src/main/java/com/flashwifi/wifip2p/datastore/PeerInformation.java @@ -16,6 +16,7 @@ public class PeerInformation { private WifiP2pInfo p2pInfo; private WifiP2pDevice wifiP2pDevice; private Date lastUpdate; + private boolean selected; // age stores how long it has been since the last signal from this peer // it is not stored in seconds but in update cycles @@ -26,6 +27,7 @@ public class PeerInformation { private NegotiationFinalization latestFinalization; public PeerInformation() { + selected = false; age = 0; } @@ -76,4 +78,12 @@ public class PeerInformation { public void setIPAddress(String IPAddress) { this.ipAddress = IPAddress; } + + public boolean isSelected() { + return selected; + } + + public void setSelected(boolean selected) { + this.selected = selected; + } } diff --git a/app/src/main/java/com/flashwifi/wifip2p/datastore/PeerListAdapter.java b/app/src/main/java/com/flashwifi/wifip2p/datastore/PeerListAdapter.java index be7f286..aeaede3 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/datastore/PeerListAdapter.java +++ b/app/src/main/java/com/flashwifi/wifip2p/datastore/PeerListAdapter.java @@ -6,6 +6,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; +import android.widget.TableRow; import android.widget.TextView; import com.flashwifi.wifip2p.R; @@ -42,6 +43,15 @@ public class PeerListAdapter extends ArrayAdapter { TextView tt3 = (TextView) v.findViewById(R.id.description); TextView tt4 = (TextView) v.findViewById(R.id.ipAddr); TextView tt5 = (TextView) v.findViewById(R.id.iotaPrice); + TableRow row = (TableRow) v.findViewById(R.id.talkingRow); + + if (row != null) { + if (p.isSelected()) { + row.setVisibility(View.VISIBLE); + } else { + row.setVisibility(View.INVISIBLE); + } + } WifiP2pDevice device = p.getWifiP2pDevice(); if (device != null) { @@ -69,6 +79,8 @@ public class PeerListAdapter extends ArrayAdapter { } + + return v; } diff --git a/app/src/main/java/com/flashwifi/wifip2p/datastore/PeerStore.java b/app/src/main/java/com/flashwifi/wifip2p/datastore/PeerStore.java index 75657ac..7604483 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/datastore/PeerStore.java +++ b/app/src/main/java/com/flashwifi/wifip2p/datastore/PeerStore.java @@ -37,16 +37,18 @@ public class PeerStore { */ public boolean updateOrCreate(PeerInformation peer) { String macAddress = peer.getWifiP2pDevice().deviceAddress; - boolean created = peers.containsKey(macAddress); + boolean exists = peers.containsKey(macAddress); - if (!created) { + if (exists) { // Temp store for the important values + peer.setSelected(peers.get(macAddress).isSelected()); } // overwrite or insert peers.put(macAddress, peer); - return created; + + return !exists; } public ArrayList getPeerArrayList() { @@ -71,6 +73,7 @@ public class PeerStore { } private PeerInformation getOrCreatePeer(String address_) { + address_ = address_.toLowerCase(); if (peers.containsKey(address_)) { return peers.get(address_); } diff --git a/app/src/main/java/com/flashwifi/wifip2p/negotiation/Negotiator.java b/app/src/main/java/com/flashwifi/wifip2p/negotiation/Negotiator.java index 056a93b..7e80cab 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/negotiation/Negotiator.java +++ b/app/src/main/java/com/flashwifi/wifip2p/negotiation/Negotiator.java @@ -19,7 +19,9 @@ 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 static final int clientTimeoutMillis = 100000; + private static final int serverTimeoutMillis = 100000; + private final String ownMacAddress; private SocketWrapper socketWrapper; @@ -56,9 +58,11 @@ public class Negotiator { ERROR } - public Negotiator(boolean isConsumer) { + public Negotiator(boolean isConsumer, String ownMacAddress) { this.isConsumer = isConsumer; gson = new GsonBuilder().create(); + this.ownMacAddress = ownMacAddress; + Log.d(TAG, "Negotiator: " + ownMacAddress); } public boolean workAsClient(String serverIPAddress) { @@ -70,14 +74,14 @@ public class Negotiator { try { // create client socket that connects to server socket = new Socket(serverIPAddress, PORT); - socket.setSoTimeout(timeoutMillis); + socket.setSoTimeout(clientTimeoutMillis); 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"; + String hello = isClient ? "HELLO I AM CLIENT" : "HELLO I AM SERVER"; socketWrapper.sendLine(hello); // Whether we want to provide a hotspot or use one @@ -113,12 +117,12 @@ public class Negotiator { try { // use the port to start serverSocket = new ServerSocket(PORT); - serverSocket.setSoTimeout(timeoutMillis); + //serverSocket.setSoTimeout(serverTimeoutMillis); Log.d(TAG, "doInBackground: Server is waiting for connection"); // accept one connection socket = serverSocket.accept(); - socket.setSoTimeout(timeoutMillis); + //socket.setSoTimeout(serverTimeoutMillis); // wrap the socket socketWrapper = new SocketWrapper(socket); @@ -126,9 +130,14 @@ public class Negotiator { // WAIT FOR CLIENT String hello = socketWrapper.getLine(); + if (hello == null) { + error(0, "no hello received"); + return false; + } + // 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) { + if (hello.contains("SERVER") && !isClient || hello.contains("CLIENT") && isClient){ error(1, "Pairing roles are broken"); return false; } @@ -176,8 +185,9 @@ public class Negotiator { // CHECK OFFER consumer_state = ConsumerState.CHECK_OFFER; NegotiationOffer offer = gson.fromJson(offerString, NegotiationOffer.class); + String otherMac = offer.getHotspotMac(); // Write offer to the PeerStore - PeerStore.getInstance().setLatestOffer(ipAddress, offer); + PeerStore.getInstance().setLatestOffer(otherMac, offer); // ToDo: implement accept or deny logic if (!true) { @@ -187,7 +197,7 @@ public class Negotiator { // SEND NegotiationAnswer // ToDo: where shall the input come from? - NegotiationOfferAnswer answer = new NegotiationOfferAnswer(true, 10); + NegotiationOfferAnswer answer = new NegotiationOfferAnswer(true, 10, ownMacAddress); String answerString = gson.toJson(answer); socketWrapper.sendLine(answerString); @@ -202,7 +212,7 @@ public class Negotiator { NegotiationFinalization finalization = gson.fromJson(finalizationString, NegotiationFinalization.class); // Write offer to the PeerStore - PeerStore.getInstance().setLatestFinalization(ipAddress, finalization); + PeerStore.getInstance().setLatestFinalization(otherMac, finalization); // Send OK @@ -220,7 +230,8 @@ public class Negotiator { hotspot_state = HotspotState.CHECK_CLIENT_REQUEST; // send offer - NegotiationOffer offer = new NegotiationOffer(1, 100, 0); + int iotaPerMegabyte = (int) (Math.random() * (1000 - 10)) + 10; + NegotiationOffer offer = new NegotiationOffer(1, 100, iotaPerMegabyte, ownMacAddress); String offerString = gson.toJson(offer); socketWrapper.sendLine(offerString); @@ -228,9 +239,15 @@ public class Negotiator { hotspot_state = HotspotState.WAIT_FOR_ANSWER; String answerString = socketWrapper.getLine(); + if (answerString == null) { + error(8, "No answer received"); + return false; + } + // Parse the answer NegotiationOfferAnswer answer = gson.fromJson(answerString, NegotiationOfferAnswer.class); - PeerStore.getInstance().setLatestOfferAnswer(ipAddress, answer); + String otherMac = answer.getConsumerMac(); + PeerStore.getInstance().setLatestOfferAnswer(otherMac, answer); // CHECK_ANSWER hotspot_state = HotspotState.CHECK_ANSWER; diff --git a/app/src/main/java/com/flashwifi/wifip2p/protocol/NegotiationOffer.java b/app/src/main/java/com/flashwifi/wifip2p/protocol/NegotiationOffer.java index 665af1f..84885da 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/protocol/NegotiationOffer.java +++ b/app/src/main/java/com/flashwifi/wifip2p/protocol/NegotiationOffer.java @@ -6,12 +6,14 @@ public class NegotiationOffer { private int minMinutes; private int maxMinutes; private int iotaPerMegabyte; + private String hotspotMac; - public NegotiationOffer(int minMinutes, int maxMinutes, int iotaPerMegabyte) { + public NegotiationOffer(int minMinutes, int maxMinutes, int iotaPerMegabyte, String hotspotMac) { this.type = "offer"; this.minMinutes = minMinutes; this.maxMinutes = maxMinutes; this.iotaPerMegabyte = iotaPerMegabyte; + this.hotspotMac = hotspotMac; } public String getType() { @@ -29,4 +31,8 @@ public class NegotiationOffer { public int getIotaPerMegabyte() { return iotaPerMegabyte; } + + public String getHotspotMac() { + return hotspotMac; + } } diff --git a/app/src/main/java/com/flashwifi/wifip2p/protocol/NegotiationOfferAnswer.java b/app/src/main/java/com/flashwifi/wifip2p/protocol/NegotiationOfferAnswer.java index fd619f7..fcf47c8 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/protocol/NegotiationOfferAnswer.java +++ b/app/src/main/java/com/flashwifi/wifip2p/protocol/NegotiationOfferAnswer.java @@ -5,11 +5,13 @@ public class NegotiationOfferAnswer { private String type; private boolean agreeToConditions; private int duranceInMinutes; + private String consumerMac; - public NegotiationOfferAnswer(boolean agreeToConditions, int duranceInMinutes) { + public NegotiationOfferAnswer(boolean agreeToConditions, int duranceInMinutes, String consumerMac) { this.type = "answerToOffer"; this.agreeToConditions = agreeToConditions; this.duranceInMinutes = duranceInMinutes; + this.consumerMac = consumerMac; } public String getType() { @@ -23,4 +25,8 @@ public class NegotiationOfferAnswer { public int getDuranceInMinutes() { return duranceInMinutes; } + + public String getConsumerMac() { + return consumerMac; + } } diff --git a/app/src/main/res/layout/itemlistview.xml b/app/src/main/res/layout/itemlistview.xml index e228781..60d5d07 100644 --- a/app/src/main/res/layout/itemlistview.xml +++ b/app/src/main/res/layout/itemlistview.xml @@ -61,5 +61,26 @@ + + + + + +