mirror of
https://github.com/DanielPollithy/flashwifi.git
synced 2025-10-16 11:45:32 +00:00
Improve P2P connectivity
This commit is contained in:
parent
01646644d1
commit
eb7f131171
@ -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);
|
||||
|
||||
@ -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<String> 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
|
||||
|
||||
@ -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<NetworkInterface> 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; i<byteMac.length; i++) {
|
||||
strBuilder.append(String.format("%02X:", byteMac[i]));
|
||||
}
|
||||
|
||||
if (strBuilder.length()>0){
|
||||
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() {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<PeerInformation> {
|
||||
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<PeerInformation> {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@ -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<PeerInformation> getPeerArrayList() {
|
||||
@ -71,6 +73,7 @@ public class PeerStore {
|
||||
}
|
||||
|
||||
private PeerInformation getOrCreatePeer(String address_) {
|
||||
address_ = address_.toLowerCase();
|
||||
if (peers.containsKey(address_)) {
|
||||
return peers.get(address_);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,5 +61,26 @@
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible"
|
||||
android:id="@+id/talkingRow">
|
||||
|
||||
|
||||
<ProgressBar
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="63dp"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Stop Talking" />
|
||||
|
||||
|
||||
</TableRow>
|
||||
|
||||
|
||||
</TableLayout>
|
||||
Loading…
Reference in New Issue
Block a user