Merge branch 'master' of github.com:DanielPollithy/flashwifi
@ -2,6 +2,7 @@
|
||||
|
||||
## What is this?
|
||||
|
||||
[WiFiota](https://tobywoerthle.github.io/flashWiFiSite/)
|
||||
|
||||
## ToDos
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@ android {
|
||||
buildToolsVersion '26.0.2'
|
||||
defaultConfig {
|
||||
applicationId "jenny.daniel.wifip2p"
|
||||
minSdkVersion 22
|
||||
targetSdkVersion 22
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 23
|
||||
multiDexEnabled = true
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
@ -48,5 +48,6 @@ dependencies {
|
||||
compile 'com.github.kenglxn.QRGen:android:2.4.0'
|
||||
compile 'me.dm7.barcodescanner:zxing:1.9.8'
|
||||
compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.10'
|
||||
compile 'com.google.api-client:google-api-client:1.23.0'
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.flashwifi.wifip2p">
|
||||
|
||||
<uses-sdk android:minSdkVersion="22" />
|
||||
<uses-sdk android:minSdkVersion="23" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
@ -14,6 +15,10 @@
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission-sdk-23 android:name="android.permission.WRITE_SETTINGS" />
|
||||
<uses-permission
|
||||
android:name="android.permission.PACKAGE_USAGE_STATS"
|
||||
tools:ignore="ProtectedPermissions"/>
|
||||
|
||||
|
||||
<application
|
||||
|
||||
BIN
app/src/main/ic_launcher-web.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
20
app/src/main/java/com/flashwifi/wifip2p/Constants.java
Normal file
@ -0,0 +1,20 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
|
||||
/**
|
||||
* Created by daniel on 23.01.18.
|
||||
*/
|
||||
|
||||
public class Constants {
|
||||
public interface ACTION {
|
||||
public static String MAIN_ACTION = "com.flashwifi.wifip2p.service.main";
|
||||
public static String PREV_ACTION = "com.flashwifi.wifip2p.service.prev";
|
||||
public static String PLAY_ACTION = "com.flashwifi.wifip2p.service.play";
|
||||
public static String NEXT_ACTION = "com.flashwifi.wifip2p.service.next";
|
||||
public static String STARTFOREGROUND_ACTION = "com.flashwifi.wifip2p.start_foreground_service";
|
||||
public static String STOPFOREGROUND_ACTION = "com.flashwifi.wifip2p.sop_foreground_service";
|
||||
}
|
||||
|
||||
public interface NOTIFICATION_ID {
|
||||
public static int FOREGROUND_SERVICE = 101;
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,7 @@ import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.flashwifi.wifip2p.iotaAPI.Requests.WalletAddressAndBalanceChecker;
|
||||
import com.flashwifi.wifip2p.iotaAPI.Requests.WalletBalanceChecker;
|
||||
|
||||
import net.glxn.qrgen.android.QRCode;
|
||||
|
||||
@ -45,7 +45,7 @@ public class FundWalletFragment extends Fragment {
|
||||
private Handler mHandler;
|
||||
|
||||
private static Boolean transactionInProgress = false;
|
||||
private WalletAddressAndBalanceChecker addressAndBalanceChecker;
|
||||
private WalletBalanceChecker addressAndBalanceChecker;
|
||||
|
||||
public FundWalletFragment() {
|
||||
// Required empty public constructor
|
||||
@ -84,19 +84,19 @@ public class FundWalletFragment extends Fragment {
|
||||
hideLoadingGIF();
|
||||
transactionInProgress = false;
|
||||
|
||||
if(returnStatus == "noError"){
|
||||
balanceTextView.setText(balance + " i");
|
||||
if(returnStatus.equals("noError")){
|
||||
balanceTextView.setText(balance);
|
||||
addressTextView.setText(depositAddress);
|
||||
createAddressQRCode(depositAddress);
|
||||
makeToastFundWalletFragment("Balance and address updated");
|
||||
}
|
||||
else if (returnStatus == "hostError"){
|
||||
else if (returnStatus.equals("hostError")){
|
||||
makeToastFundWalletFragment("Unable to reach host (node)");
|
||||
}
|
||||
else if (returnStatus == "addressError"){
|
||||
else if (returnStatus.equals("addressError")){
|
||||
makeToastFundWalletFragment("Error getting address");
|
||||
}
|
||||
else if (returnStatus == "balanceError"){
|
||||
else if (returnStatus.equals("balanceError")){
|
||||
makeToastFundWalletFragment("Error getting balance. May not be able to resolve host/node");
|
||||
}
|
||||
else{
|
||||
@ -191,7 +191,7 @@ public class FundWalletFragment extends Fragment {
|
||||
|
||||
private void getBalance(){
|
||||
transactionInProgress = true;
|
||||
addressAndBalanceChecker = new WalletAddressAndBalanceChecker(getActivity(),getActivity().getString(R.string.preference_file_key),seed, mHandler,FUND_WALLET,true);
|
||||
addressAndBalanceChecker = new WalletBalanceChecker(getActivity(),getActivity().getString(R.string.preference_file_key),seed, mHandler,FUND_WALLET,true);
|
||||
addressAndBalanceChecker.execute();
|
||||
}
|
||||
|
||||
|
||||
@ -1,17 +1,27 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Example;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.IotaFlashBridge;
|
||||
@ -71,6 +81,21 @@ public class HomeActivity extends AppCompatActivity {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_home);
|
||||
|
||||
|
||||
ActivityCompat.requestPermissions(HomeActivity.this,
|
||||
new String[]{
|
||||
Manifest.permission.ACCESS_WIFI_STATE,
|
||||
Manifest.permission.CHANGE_WIFI_STATE,
|
||||
Manifest.permission.CHANGE_NETWORK_STATE,
|
||||
Manifest.permission.INTERNET,
|
||||
Manifest.permission.ACCESS_NETWORK_STATE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.READ_PHONE_STATE,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.CAMERA
|
||||
},
|
||||
1);
|
||||
|
||||
// iotalibflash
|
||||
String iotaflash = readFile("iotaflash");
|
||||
String iotaflashhelper = readFile("iotaflashhelper");
|
||||
@ -87,6 +112,55 @@ public class HomeActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode,
|
||||
String permissions[], int[] grantResults) {
|
||||
switch (requestCode) {
|
||||
case 1: {
|
||||
|
||||
// If request is cancelled, the result arrays are empty.
|
||||
int i = 0;
|
||||
if (grantResults.length > 0) {
|
||||
boolean ok = true;
|
||||
for (int grantResult: grantResults) {
|
||||
if (grantResult != PackageManager.PERMISSION_GRANTED) {
|
||||
ok = false;
|
||||
Log.d(TAG, "onRequestPermissionsResult: denied: " + permissions[i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (ok) {
|
||||
Toast.makeText(HomeActivity.this, "Permissions granted", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(HomeActivity.this, "Permissions denied", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
|
||||
int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
|
||||
android.os.Process.myUid(), getPackageName());
|
||||
if (mode != AppOpsManager.MODE_ALLOWED) {
|
||||
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
int mode2 = appOps.checkOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS,
|
||||
android.os.Process.myUid(), getPackageName());
|
||||
if (mode2 != AppOpsManager.MODE_ALLOWED) {
|
||||
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
|
||||
startActivity(intent);
|
||||
}
|
||||
} else {
|
||||
|
||||
// permission denied, boo! Disable the
|
||||
// functionality that depends on this permission.
|
||||
Toast.makeText(HomeActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
// other 'case' lines to check for other
|
||||
// permissions this app might request
|
||||
}
|
||||
}
|
||||
|
||||
private void setProgressBar(int percentage) {
|
||||
ProgressBar prog = (ProgressBar) findViewById(R.id.progressbar);
|
||||
prog.setProgress(percentage);
|
||||
@ -137,7 +211,10 @@ public class HomeActivity extends AppCompatActivity {
|
||||
} else {
|
||||
final EditText field = (EditText) findViewById(R.id.password);
|
||||
field.setText("");
|
||||
Snackbar.make(view, getString(R.string.wrong_password), Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
Toast toast= Toast.makeText(getApplicationContext(),
|
||||
getString(R.string.wrong_password), Toast.LENGTH_SHORT);
|
||||
toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 0);
|
||||
toast.show();
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,9 +254,17 @@ public class HomeActivity extends AppCompatActivity {
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View view) {
|
||||
setProgressBar(50);
|
||||
String password = new_password_field.getText().toString();
|
||||
storeNewSeed(seed, password);
|
||||
if (new_password_field.getText().toString().length() > 0) {
|
||||
setProgressBar(50);
|
||||
String password = new_password_field.getText().toString();
|
||||
storeNewSeed(seed, password);
|
||||
} else {
|
||||
Toast toast= Toast.makeText(getApplicationContext(),
|
||||
"No blank password allowed", Toast.LENGTH_SHORT);
|
||||
toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 0);
|
||||
toast.show();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ToggleButton;
|
||||
|
||||
@ -33,8 +34,6 @@ public class HotspotFragment extends Fragment {
|
||||
|
||||
private int numberConnectedPeers = 0;
|
||||
|
||||
WiFiDirectBroadcastService mService;
|
||||
boolean mBound = false;
|
||||
BroadcastReceiver updateUIReceiver;
|
||||
|
||||
public HotspotFragment() {
|
||||
@ -72,33 +71,34 @@ public class HotspotFragment extends Fragment {
|
||||
|
||||
private void updateUi(Intent intent) {
|
||||
Log.d(TAG, "updateUi: Got some network data into the hotspot fragment");
|
||||
String numberAvailableDevices = Integer.toString(mService.getArrayList().size());
|
||||
String numberAvailableDevices = Integer.toString(getmService().getArrayList().size());
|
||||
TextView text = (TextView) getActivity().findViewById(R.id.numberPeers);
|
||||
text.setVisibility(View.VISIBLE);
|
||||
text.setText(String.format("%s peers", numberAvailableDevices));
|
||||
final View activity_view = getActivity().findViewById(R.id.drawer_layout);
|
||||
|
||||
//if (intent.hasExtra("what") && intent.getExtras().getString("what", "").equals("connectivity_changed")) {
|
||||
|
||||
NetworkInfo network_info = mService.getNetwork_info();
|
||||
WifiP2pInfo p2p_info = mService.getP2p_info();
|
||||
WifiP2pGroup wifiP2pGroup = mService.getP2p_group();
|
||||
NetworkInfo network_info = getmService().getNetwork_info();
|
||||
WifiP2pInfo p2p_info = getmService().getP2p_info();
|
||||
WifiP2pGroup wifiP2pGroup = getmService().getP2p_group();
|
||||
|
||||
//if (intent.hasExtra("currentDeviceConnected")) {
|
||||
if (intent.hasExtra("currentDeviceConnected")) {
|
||||
//String macAddress = intent.getExtras().getString("currentDeviceConnected");
|
||||
if (network_info.getState() == NetworkInfo.State.CONNECTED) {
|
||||
// ToDo: look for the other device and make sure we are only two
|
||||
|
||||
if (p2p_info.isGroupOwner) {
|
||||
Snackbar.make(activity_view, "You are the group owner", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
mService.startNegotiationServer(false, null);
|
||||
getmService().startNegotiationServer(false, null);
|
||||
} else {
|
||||
InetAddress groupOwnerAddress = p2p_info.groupOwnerAddress;
|
||||
Snackbar.make(activity_view, "You are only a member of the group", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
mService.startNegotiationClient(groupOwnerAddress, false, null);
|
||||
getmService().startNegotiationClient(groupOwnerAddress, false, null);
|
||||
}
|
||||
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -109,29 +109,58 @@ public class HotspotFragment extends Fragment {
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
getActivity().unbindService(mConnection);
|
||||
getActivity().unregisterReceiver(updateUIReceiver);
|
||||
mBound = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
initFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
initFragment();
|
||||
}
|
||||
|
||||
public WiFiDirectBroadcastService getmService() {
|
||||
MainActivity act = (MainActivity) getActivity();
|
||||
return act.getmService();
|
||||
}
|
||||
|
||||
private void initFragment(){
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction("com.flashwifi.wifip2p.update_ui");
|
||||
filter.addAction("com.flashwifi.wifip2p.start_roaming");
|
||||
filter.addAction("com.flashwifi.wifip2p.stop_roaming");
|
||||
|
||||
updateUIReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
updateUi(intent);
|
||||
if (getActivity() == null) {
|
||||
Log.d(TAG, "onReceive: getActivity is null");
|
||||
return;
|
||||
}
|
||||
if (intent.getAction().equals("com.flashwifi.wifip2p.start_roaming")) {
|
||||
String mac = intent.getStringExtra("peer_mac_address");
|
||||
ToggleButton toggle = (ToggleButton) getActivity().findViewById(R.id.startAPButton);
|
||||
toggle.setChecked(false);
|
||||
ProgressBar progressBar = (ProgressBar) getActivity().findViewById(R.id.progressbarAP);
|
||||
progressBar.setVisibility(View.INVISIBLE);
|
||||
} else if (intent.getAction().equals("com.flashwifi.wifip2p.stop_roaming")) {
|
||||
ToggleButton toggle = (ToggleButton) getActivity().findViewById(R.id.startAPButton);
|
||||
toggle.setChecked(false);
|
||||
ProgressBar progressBar = (ProgressBar) getActivity().findViewById(R.id.progressbarAP);
|
||||
progressBar.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
updateUi(intent);
|
||||
}
|
||||
}
|
||||
};
|
||||
getActivity().registerReceiver(updateUIReceiver, filter);
|
||||
|
||||
// Bind to Service
|
||||
Intent intent = new Intent(getActivity(), WiFiDirectBroadcastService.class);
|
||||
getActivity().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
||||
getActivity().registerReceiver(updateUIReceiver, filter);
|
||||
|
||||
initUI();
|
||||
|
||||
@ -157,36 +186,25 @@ public class HotspotFragment extends Fragment {
|
||||
// ToDo: Move this to a async task
|
||||
//boolean status = (isNetworkConnected() && isInternetAvailable());
|
||||
}
|
||||
|
||||
private boolean isNetworkConnected() {
|
||||
ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
return cm.getActiveNetworkInfo() != null;
|
||||
}
|
||||
|
||||
public boolean isInternetAvailable() {
|
||||
try {
|
||||
InetAddress ipAddr = InetAddress.getByName("google.com");
|
||||
return !ipAddr.getHostAddress().equals("");
|
||||
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void startDiscovery() {
|
||||
final View activity_view = getActivity().findViewById(R.id.drawer_layout);
|
||||
if (mBound) {
|
||||
mService.setInRoleConsumer(false);
|
||||
mService.setInRoleHotspot(true);
|
||||
mService.getPeerList(new WifiP2pManager.ActionListener() {
|
||||
if (getmService() != null) {
|
||||
getmService().setInRoleConsumer(false);
|
||||
getmService().setInRoleHotspot(true);
|
||||
getmService().getPeerList(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
// show progress wheel
|
||||
ProgressBar progressBar = (ProgressBar) getActivity().findViewById(R.id.progressbarAP);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(int reasonCode) {
|
||||
Snackbar.make(activity_view, "Aaaargh :( Searching problem!", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
ProgressBar progressBar = (ProgressBar) getActivity().findViewById(R.id.progressbarAP);
|
||||
progressBar.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -195,20 +213,24 @@ public class HotspotFragment extends Fragment {
|
||||
|
||||
private void stopDiscovery() {
|
||||
final View activity_view = getActivity().findViewById(R.id.drawer_layout);
|
||||
if (mBound) {
|
||||
mService.stopDiscovery(new WifiP2pManager.ActionListener() {
|
||||
if (getmService() != null) {
|
||||
getmService().stopDiscovery(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
mService.setInRoleConsumer(false);
|
||||
mService.setInRoleHotspot(false);
|
||||
getmService().setInRoleConsumer(false);
|
||||
getmService().setInRoleHotspot(false);
|
||||
Snackbar.make(activity_view, "Stopped Hotspot mode", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
ProgressBar progressBar = (ProgressBar) getActivity().findViewById(R.id.progressbarAP);
|
||||
progressBar.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(int reasonCode) {
|
||||
mService.setInRoleConsumer(false);
|
||||
mService.setInRoleHotspot(false);
|
||||
getmService().setInRoleConsumer(false);
|
||||
getmService().setInRoleHotspot(false);
|
||||
Snackbar.make(activity_view, "Aaaargh :( Problem stopping discovery", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
ProgressBar progressBar = (ProgressBar) getActivity().findViewById(R.id.progressbarAP);
|
||||
progressBar.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -218,10 +240,16 @@ public class HotspotFragment extends Fragment {
|
||||
private void initUI() {
|
||||
final View activity_view = getActivity().findViewById(R.id.drawer_layout);
|
||||
final ToggleButton button = (ToggleButton) getActivity().findViewById(R.id.startAPButton);
|
||||
//button.setChecked(mService.isInRoleHotspot());
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (getmService() != null) {
|
||||
if (!getmService().isSetup()) {
|
||||
Snackbar.make(activity_view, "Please enable WiFi P2P", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
button.setChecked(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (button.isChecked()) {
|
||||
startDiscovery();
|
||||
Snackbar.make(activity_view, "Start Discovery Mode", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
@ -232,25 +260,4 @@ public class HotspotFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Defines callbacks for service binding, passed to bindService() */
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className,
|
||||
IBinder service) {
|
||||
// We've bound to LocalService, cast the IBinder and get LocalService instance
|
||||
WiFiDirectBroadcastService.LocalBinder binder = (WiFiDirectBroadcastService.LocalBinder) service;
|
||||
mService = binder.getService();
|
||||
mBound = true;
|
||||
|
||||
final ToggleButton button = (ToggleButton) getActivity().findViewById(R.id.startAPButton);
|
||||
button.setChecked(mService.isInRoleHotspot());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName arg0) {
|
||||
mBound = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
@ -8,30 +9,42 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.wifi.p2p.WifiP2pManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.design.widget.NavigationView;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.CompoundButton;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Switch;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.flashwifi.wifip2p.billing.Accountant;
|
||||
import com.flashwifi.wifip2p.broadcast.WiFiDirectBroadcastService;
|
||||
import com.flashwifi.wifip2p.iotaAPI.Requests.WalletBalanceChecker;
|
||||
|
||||
public class MainActivity extends AppCompatActivity
|
||||
implements NavigationView.OnNavigationItemSelectedListener
|
||||
{
|
||||
|
||||
private static final String TAG = "MainAct";
|
||||
private String password;
|
||||
private String seed;
|
||||
private static final int PREF_UPDATE = 2;
|
||||
private static final int BALANCE_RETRIEVE_TASK_COMPLETE = 1;
|
||||
private Handler balanceHandler;
|
||||
|
||||
private DrawerLayout mDrawerLayout;
|
||||
private ListView mDrawerList;
|
||||
@ -46,22 +59,75 @@ public class MainActivity extends AppCompatActivity
|
||||
private void subscribeToBroadcasts() {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction("com.flashwifi.wifip2p.start_roaming");
|
||||
filter.addAction("com.flashwifi.wifip2p.stop_roaming");
|
||||
|
||||
updateUIReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
try {
|
||||
// hide progress bar
|
||||
ProgressBar progressConnection = (ProgressBar) findViewById(R.id.progressConnection);
|
||||
progressConnection.setVisibility(View.VISIBLE);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
if (intent.getAction().equals("com.flashwifi.wifip2p.start_roaming")) {
|
||||
startRoamingView(intent.getStringExtra("peer_mac_address"),
|
||||
intent.getStringExtra("ssid"),
|
||||
intent.getStringExtra("key"));
|
||||
} else if (intent.getAction().equals("com.flashwifi.wifip2p.stop_roaming")) {
|
||||
Log.d(TAG, "onReceive: Reset billing state");
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
registerReceiver(updateUIReceiver, filter);
|
||||
}
|
||||
|
||||
public boolean isTheServiceRunning() {
|
||||
return isMyServiceRunning(WiFiDirectBroadcastService.class);
|
||||
}
|
||||
|
||||
private boolean isMyServiceRunning(Class<?> serviceClass) {
|
||||
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
|
||||
if (serviceClass.getName().equals(service.service.getClassName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
//unbindWifiBroadcast();
|
||||
unsubscribeFromBroadcast();
|
||||
}
|
||||
|
||||
private void unbindWifiBroadcast() {
|
||||
try {unregisterReceiver(updateUIReceiver);
|
||||
unbindService(mConnection);
|
||||
}
|
||||
catch(IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
initEverything();
|
||||
}
|
||||
|
||||
private void unsubscribeFromBroadcast() {
|
||||
try {
|
||||
unregisterReceiver(updateUIReceiver);
|
||||
updateUIReceiver = null;
|
||||
} catch (Exception e){
|
||||
}
|
||||
}
|
||||
|
||||
private void initUi() {
|
||||
final Switch switch_ = (Switch) findViewById(R.id.wifiSwitch);
|
||||
/*final Switch switch_ = (Switch) findViewById(R.id.wifiSwitch);
|
||||
switch_.setOnCheckedChangeListener(new Switch.OnCheckedChangeListener() {
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
if (isChecked) {
|
||||
@ -75,16 +141,27 @@ public class MainActivity extends AppCompatActivity
|
||||
mService.disableService();
|
||||
}
|
||||
}
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_main);
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
// get the secrets from the login screen
|
||||
Intent intent = getIntent();
|
||||
password = intent.getStringExtra("password");
|
||||
seed = intent.getStringExtra("seed");
|
||||
|
||||
setBalanceHandler();
|
||||
updateBalance();
|
||||
|
||||
Accountant.getInstance().setSeed(seed);
|
||||
|
||||
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
|
||||
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
|
||||
@ -94,25 +171,46 @@ public class MainActivity extends AppCompatActivity
|
||||
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
|
||||
navigationView.setNavigationItemSelectedListener(this);
|
||||
|
||||
// get the secrets from the login screen
|
||||
Intent intent = getIntent();
|
||||
password = intent.getStringExtra("password");
|
||||
seed = intent.getStringExtra("seed");
|
||||
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
|
||||
|
||||
beginForegroundService();
|
||||
|
||||
// Bind to Service
|
||||
Intent intent2 = new Intent(this, WiFiDirectBroadcastService.class);
|
||||
bindService(intent2, mConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
public WiFiDirectBroadcastService getmService() {
|
||||
if (mBound) {
|
||||
return mService;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void beginForegroundService() {
|
||||
if (!isTheServiceRunning()) {
|
||||
Intent startIntent = new Intent(MainActivity.this, WiFiDirectBroadcastService.class);
|
||||
startIntent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
|
||||
startService(startIntent);
|
||||
} else {
|
||||
Log.d(TAG, "beginForegroundService: Service is already running");
|
||||
}
|
||||
}
|
||||
|
||||
private void initEverything() {
|
||||
subscribeToBroadcasts();
|
||||
initUi();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
unregisterReceiver(updateUIReceiver);
|
||||
unbindService(mConnection);
|
||||
|
||||
try {unregisterReceiver(updateUIReceiver);
|
||||
unbindService(mConnection);
|
||||
}
|
||||
catch(IllegalArgumentException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -148,16 +246,16 @@ public class MainActivity extends AppCompatActivity
|
||||
startSearchFragment();
|
||||
} else if (id == R.id.nav_start) {
|
||||
startHotspotFragment();
|
||||
} else if (id == R.id.nav_itp) {
|
||||
|
||||
// } else if (id == R.id.nav_itp) {
|
||||
//
|
||||
} else if (id == R.id.nav_fund) {
|
||||
startFundWalletFragment();
|
||||
} else if (id == R.id.nav_withdraw) {
|
||||
startWithdrawWalletFragment();
|
||||
} else if (id == R.id.nav_conditions) {
|
||||
// } else if (id == R.id.nav_conditions) {
|
||||
|
||||
} else if (id == R.id.nav_settings) {
|
||||
|
||||
startSettingsFragment();
|
||||
}
|
||||
|
||||
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||
@ -165,9 +263,37 @@ public class MainActivity extends AppCompatActivity
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean settingsAreReady(){
|
||||
// check whether all necessary settings were set by the user
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
String[] intVariables = new String[]{
|
||||
"edit_text_sell_min_minutes",
|
||||
"edit_text_sell_price",
|
||||
"edit_text_sell_max_minutes",
|
||||
"edit_text_buy_price",
|
||||
"edit_text_client_minutes"
|
||||
};
|
||||
String val;
|
||||
for (String variable: intVariables) {
|
||||
val = prefs.getString(variable, null);
|
||||
if (val == null) {
|
||||
Log.d("Variable not set: ", "settingsAreReady: " + variable);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateBalance() {
|
||||
WalletBalanceChecker balanceChecker = new WalletBalanceChecker(this,this.getString(R.string.preference_file_key),seed, balanceHandler,PREF_UPDATE,true);
|
||||
balanceChecker.execute();
|
||||
}
|
||||
|
||||
public void startSearchFragment() {
|
||||
if (mBound && mService.isInRoleHotspot()) {
|
||||
Toast.makeText(this, "Can't start search because you are hotspot", Toast.LENGTH_SHORT).show();
|
||||
} else if (!settingsAreReady()) {
|
||||
Toast.makeText(this, "Navigate to settings and assign all variables", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Fragment fragment = new SearchFragment();
|
||||
|
||||
@ -181,6 +307,21 @@ public class MainActivity extends AppCompatActivity
|
||||
}
|
||||
|
||||
private void startRoamingView(String macAddress, String ssid, String key){
|
||||
// disable WiFi P2P
|
||||
if (mBound) {
|
||||
mService.stopDiscovery(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Log.d("MainAct", "discovery stopped");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(int i) {
|
||||
Log.d("MainAct", "discovery could not be stopped");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Intent intent = new Intent(this, RoamingActivity.class);
|
||||
intent.putExtra("address", macAddress);
|
||||
intent.putExtra("key", key);
|
||||
@ -191,11 +332,11 @@ public class MainActivity extends AppCompatActivity
|
||||
public void startHotspotFragment() {
|
||||
if (mBound && mService.isInRoleConsumer()) {
|
||||
Toast.makeText(this, "Can't start hotspot because you are searching", Toast.LENGTH_SHORT).show();
|
||||
} else if (!settingsAreReady()) {
|
||||
Toast.makeText(this, "Navigate to settings and assign all variables", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Fragment fragment = new HotspotFragment();
|
||||
Bundle args = new Bundle();
|
||||
//args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
|
||||
//fragment.setArguments(args);
|
||||
|
||||
// Insert the fragment by replacing any existing fragment
|
||||
FragmentManager fragmentManager = getFragmentManager();
|
||||
@ -235,6 +376,20 @@ public class MainActivity extends AppCompatActivity
|
||||
.commit();
|
||||
}
|
||||
|
||||
private void startSettingsFragment() {
|
||||
Fragment fragment = new SettingsFragment();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("seed", seed);
|
||||
fragment.setArguments(bundle);
|
||||
fragment.setRetainInstance(true);
|
||||
|
||||
// Insert the fragment by replacing any existing fragment
|
||||
FragmentManager fragmentManager = getFragmentManager();
|
||||
fragmentManager.beginTransaction()
|
||||
.replace(R.id.content_frame, fragment)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||
@ -270,6 +425,7 @@ public class MainActivity extends AppCompatActivity
|
||||
WiFiDirectBroadcastService.LocalBinder binder = (WiFiDirectBroadcastService.LocalBinder) service;
|
||||
mService = binder.getService();
|
||||
mBound = true;
|
||||
mService.enableService();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -277,4 +433,34 @@ public class MainActivity extends AppCompatActivity
|
||||
mBound = false;
|
||||
}
|
||||
};
|
||||
|
||||
private void setBalanceHandler() {
|
||||
//Handle post-asynctask activities
|
||||
balanceHandler = new Handler(Looper.getMainLooper()) {
|
||||
@Override
|
||||
public void handleMessage(Message inputMessage) {
|
||||
switch (inputMessage.what) {
|
||||
case BALANCE_RETRIEVE_TASK_COMPLETE:
|
||||
AddressBalanceTransfer addressBalanceTransfer = (AddressBalanceTransfer) inputMessage.obj;
|
||||
String returnStatus = addressBalanceTransfer.getMessage();
|
||||
if (returnStatus.equals("noError")) {
|
||||
makeToastBalance("Balance updated");
|
||||
} else if (returnStatus.equals("hostError")) {
|
||||
makeToastBalance("Unable to reach host (node)");
|
||||
} else if (returnStatus.equals("addressError")) {
|
||||
makeToastBalance("Error getting address");
|
||||
} else if (returnStatus.equals("balanceError")) {
|
||||
makeToastBalance("Error getting balance. May not be able to resolve host/node");
|
||||
} else {
|
||||
makeToastBalance("Unknown error");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void makeToastBalance(String message) {
|
||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
@ -26,10 +27,12 @@ import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.flashwifi.wifip2p.billing.Accountant;
|
||||
@ -37,6 +40,8 @@ import com.flashwifi.wifip2p.broadcast.WiFiDirectBroadcastService;
|
||||
import com.flashwifi.wifip2p.datastore.PeerStore;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationFinalization;
|
||||
|
||||
import org.w3c.dom.Text;
|
||||
|
||||
|
||||
public class RoamingActivity extends AppCompatActivity {
|
||||
private static final String TAG = "RoamingActivity";
|
||||
@ -59,6 +64,7 @@ public class RoamingActivity extends AppCompatActivity {
|
||||
|
||||
private Button stopButton;
|
||||
private boolean endRoamingFlag = false;
|
||||
private boolean initiatedEnd;
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
@ -93,20 +99,40 @@ public class RoamingActivity extends AppCompatActivity {
|
||||
Log.d(TAG, "updateUi: message=" + message);
|
||||
CheckBox apConnected = (CheckBox)findViewById(R.id.accessPointActive);
|
||||
CheckBox flashEstablished = (CheckBox)findViewById(R.id.flashEstablished);
|
||||
CheckBox channelFunded = (CheckBox)findViewById(R.id.channelFunded);
|
||||
if (message.equals("AP SUCCESS")) {
|
||||
apConnected.setChecked(true);
|
||||
mService.resetBillingState();
|
||||
// when the AP is setup we can start the server
|
||||
startBillingProtocol();
|
||||
} else if (message.equals("AP FAILED")) {
|
||||
apConnected.setChecked(false);
|
||||
Toast.makeText(getApplicationContext(), "Could not create Access point", Toast.LENGTH_LONG).show();
|
||||
exitRoaming();
|
||||
} else if (message.equals("AP STOPPED")) {
|
||||
apConnected.setChecked(false);
|
||||
} else if (message.equals("Channel established")) {
|
||||
flashEstablished.setChecked(true);
|
||||
} else if (message.equals("Start Channel funding")) {
|
||||
// start the task
|
||||
mService.fundChannel(address);
|
||||
} else if (message.equals("Channel funded")) {
|
||||
channelFunded.setChecked(true);
|
||||
} else if (message.equals("Billing")) {
|
||||
updateBillingCard();
|
||||
} else if (message.equals("Channel closed")) {
|
||||
exitRoaming();
|
||||
if (mService.isInRoleHotspot()) {
|
||||
showRetransferCard();
|
||||
}
|
||||
} else if (message.equals("Socket exception")) {
|
||||
//Toast.makeText(getApplicationContext(), "Socket exception", Toast.LENGTH_LONG).show();
|
||||
//exitRoaming();
|
||||
} else if (message.equals("Exit")) {
|
||||
Toast.makeText(getApplicationContext(), "Can't connect", Toast.LENGTH_LONG).show();
|
||||
exitRoaming();
|
||||
}
|
||||
// ToDo: add a critical error that uses exitRoaming()
|
||||
}
|
||||
|
||||
}
|
||||
@ -118,25 +144,50 @@ public class RoamingActivity extends AppCompatActivity {
|
||||
|
||||
}
|
||||
|
||||
private void stopRoamingBroadcast() {
|
||||
Intent local = new Intent();
|
||||
local.setAction("com.flashwifi.wifip2p.stop_roaming");
|
||||
this.sendBroadcast(local);
|
||||
}
|
||||
|
||||
private void showRetransferCard() {
|
||||
CardView cardView = (CardView) findViewById(R.id.card_view_tangle_attachment);
|
||||
cardView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
private void updateBillingCard() {
|
||||
CardView summaryView = (CardView) findViewById(R.id.card_view_overview);
|
||||
if (summaryView.getVisibility() != View.VISIBLE) {
|
||||
summaryView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
String minutes = Integer.toString(Accountant.getInstance().getTotalDurance());
|
||||
String megabytes_max = Integer.toString(Accountant.getInstance().getBookedMegabytes());
|
||||
String megabytes_used = Integer.toString(Accountant.getInstance().getTotalMegabytes());
|
||||
String iotas_transferred = Integer.toString(Accountant.getInstance().getTotalIotaPrice());
|
||||
int minutes = Accountant.getInstance().getTotalDurance() / 60;
|
||||
int minutes_max = Accountant.getInstance().getBookedMinutes();
|
||||
int bytes_max = Accountant.getInstance().getBookedBytes();
|
||||
int bytes_used = Accountant.getInstance().getTotalBytes();
|
||||
int iotas_transferred = Accountant.getInstance().getTotalIotaPrice();
|
||||
int iotas_max = Accountant.getInstance().getTotalIotaDeposit();
|
||||
|
||||
TextView summaryMinutes = (TextView) findViewById(R.id.summaryMinutes);
|
||||
summaryMinutes.setText(String.format("%s minutes active", minutes));
|
||||
summaryMinutes.setText(String.format("%d/%d minutes active", minutes, minutes_max));
|
||||
|
||||
TextView summaryMegabytes = (TextView) findViewById(R.id.summaryMegabytes);
|
||||
summaryMegabytes.setText(String.format("%s/%s Megabytes roamed", megabytes_used, megabytes_max));
|
||||
|
||||
summaryMegabytes.setText(String.format("%d/%d Megabytes roamed", bytes_used, bytes_max));
|
||||
|
||||
TextView summaryIota = (TextView) findViewById(R.id.summaryIota);
|
||||
summaryMegabytes.setText(String.format("%s Iota transferred", iotas_transferred));
|
||||
summaryIota.setText(String.format("%d/%d Iota transferred", iotas_transferred, iotas_max));
|
||||
|
||||
ProgressBar progressMinutes = (ProgressBar) findViewById(R.id.progressbarDurance);
|
||||
progressMinutes.setMax(minutes_max);
|
||||
progressMinutes.setProgress(minutes);
|
||||
|
||||
ProgressBar progressMegabytes = (ProgressBar) findViewById(R.id.progressbarMegabytes);
|
||||
progressMegabytes.setMax(bytes_max);
|
||||
progressMegabytes.setProgress(bytes_used);
|
||||
|
||||
ProgressBar progressIota = (ProgressBar) findViewById(R.id.progressbarIota);
|
||||
progressIota.setProgress(iotas_transferred);
|
||||
progressIota.setMax(iotas_max);
|
||||
|
||||
|
||||
}
|
||||
@ -144,9 +195,9 @@ public class RoamingActivity extends AppCompatActivity {
|
||||
private void startBillingProtocol() {
|
||||
// setup the flash channel etc...
|
||||
if (mService.isInRoleHotspot()) {
|
||||
mService.startBillingServer();
|
||||
mService.startBillingServer(address);
|
||||
} else {
|
||||
mService.startBillingClient();
|
||||
mService.startBillingClient(address);
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,6 +217,8 @@ public class RoamingActivity extends AppCompatActivity {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_roaming);
|
||||
|
||||
Accountant.getInstance().reset();
|
||||
|
||||
// Get the Intent that started this activity and extract the string
|
||||
Intent intent = getIntent();
|
||||
name = intent.getStringExtra("name");
|
||||
@ -179,78 +232,12 @@ public class RoamingActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void cancelNotification() {
|
||||
NotificationManager mNotificationManager =
|
||||
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
mNotificationManager.cancel(1);
|
||||
}
|
||||
|
||||
|
||||
private void showNotification() {
|
||||
// The id of the channel.
|
||||
String CHANNEL_ID = "com.flashwifi.wifip2p.roaming_1";
|
||||
|
||||
String contentText = mService.isInRoleHotspot() ? "You are providing" : "You are consuming";
|
||||
|
||||
// ToDo: make this work on high API version
|
||||
NotificationCompat.Builder mBuilder =
|
||||
new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.icon_tethering_on)
|
||||
.setContentTitle("IOTA HOTSPOT")
|
||||
.setContentText(contentText);
|
||||
// Creates an explicit intent for an Activity in your app
|
||||
Intent resultIntent = new Intent(this, RoamingActivity.class);
|
||||
|
||||
// The stack builder object will contain an artificial back stack for the
|
||||
// started Activity.
|
||||
// This ensures that navigating backward from the Activity leads out of
|
||||
// your app to the Home screen.
|
||||
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
|
||||
// Adds the back stack for the Intent (but not the Intent itself)
|
||||
stackBuilder.addParentStack(RoamingActivity.class);
|
||||
// Adds the Intent that starts the Activity to the top of the stack
|
||||
stackBuilder.addNextIntent(resultIntent);
|
||||
PendingIntent resultPendingIntent =
|
||||
stackBuilder.getPendingIntent(
|
||||
0,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
);
|
||||
mBuilder.setContentIntent(resultPendingIntent);
|
||||
NotificationManager mNotificationManager =
|
||||
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
// mNotificationId is a unique integer your app uses to identify the
|
||||
// notification. For example, to cancel the notification, you can pass its ID
|
||||
// number to NotificationManager.cancel().
|
||||
mNotificationManager.notify(1, mBuilder.build());
|
||||
}
|
||||
|
||||
|
||||
private void initUI() {
|
||||
//final EditText input = (EditText) findViewById(R.id.chat_input);
|
||||
//Button button = (Button) findViewById(R.id.btn_send);
|
||||
/*button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View view) {
|
||||
addMessageRight(name, input.getText().toString());
|
||||
// send the message to the peer
|
||||
//mService.sendMessageToSocketServer(groupOwnerAddress, input.getText().toString());
|
||||
}
|
||||
});*/
|
||||
|
||||
/*FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
|
||||
fab.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View view) {
|
||||
toggleHotspot();
|
||||
}
|
||||
});
|
||||
|
||||
listView = (ListView) findViewById(R.id.peer_list);
|
||||
arrayList = new ArrayList<>();
|
||||
|
||||
listAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, arrayList);
|
||||
listView.setAdapter(listAdapter);*/
|
||||
}
|
||||
|
||||
/** Defines callbacks for service binding, passed to bindService() */
|
||||
@ -294,10 +281,25 @@ public class RoamingActivity extends AppCompatActivity {
|
||||
}
|
||||
});
|
||||
|
||||
showNotification();
|
||||
updateBillingCard();
|
||||
|
||||
// ToDo: update notification
|
||||
//showNotification();
|
||||
}
|
||||
|
||||
private void endRoaming() {
|
||||
if (!initiatedEnd) {
|
||||
initiatedEnd = true;
|
||||
Accountant.getInstance().setCloseAfterwards(true);
|
||||
// the next bill will send the close request
|
||||
// meanwhile show a loading icon
|
||||
ProgressBar stopProgressBar = (ProgressBar) findViewById(R.id.stopProgressBar);
|
||||
stopProgressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void exitRoaming() {
|
||||
Accountant.getInstance().setCloseAfterwards(true);
|
||||
endRoamingFlag = true;
|
||||
cancelNotification();
|
||||
if (mService.isInRoleHotspot()){
|
||||
@ -306,7 +308,26 @@ public class RoamingActivity extends AppCompatActivity {
|
||||
mService.disconnectAP();
|
||||
}
|
||||
mService.setRoaming(false);
|
||||
mService.resetBillingState();
|
||||
mService.setInRoleConsumer(false);
|
||||
mService.setInRoleHotspot(false);
|
||||
|
||||
PeerStore.getInstance().clear();
|
||||
|
||||
// hide the spinner and the stop button
|
||||
ProgressBar stopProgressBar = (ProgressBar) findViewById(R.id.stopProgressBar);
|
||||
stopProgressBar.setVisibility(View.GONE);
|
||||
Button stopButton = (Button) findViewById(R.id.stopRoamingButton);
|
||||
stopButton.setVisibility(View.GONE);
|
||||
|
||||
TextView stopText = (TextView) findViewById(R.id.stopText);
|
||||
stopText.setVisibility(View.VISIBLE);
|
||||
|
||||
stopRoamingBroadcast();
|
||||
|
||||
Toast.makeText(getApplicationContext(), "Press BACK now", Toast.LENGTH_LONG).show();
|
||||
initiatedEnd = false;
|
||||
//finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -21,6 +21,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
import android.widget.ToggleButton;
|
||||
|
||||
@ -32,6 +33,7 @@ import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.flashwifi.wifip2p.broadcast.WiFiDirectBroadcastService;
|
||||
import com.flashwifi.wifip2p.iotaFlashWrapper.Main;
|
||||
|
||||
/**
|
||||
* Fragment that appears in the "content_frame", shows a planet
|
||||
@ -40,9 +42,7 @@ public class SearchFragment extends Fragment {
|
||||
|
||||
public final static String TAG = "SearchActivity";
|
||||
|
||||
WiFiDirectBroadcastService mService;
|
||||
boolean mBound = false;
|
||||
BroadcastReceiver updateUIReceiver;
|
||||
BroadcastReceiver updateUIReceiver = null;
|
||||
|
||||
ArrayList<String> arrayList;
|
||||
PeerListAdapter peerListAdapter;
|
||||
@ -63,6 +63,14 @@ public class SearchFragment extends Fragment {
|
||||
return rootView;
|
||||
}
|
||||
|
||||
public WiFiDirectBroadcastService getmService() {
|
||||
MainActivity act = (MainActivity) getActivity();
|
||||
if (act != null) {
|
||||
return act.getmService();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -86,8 +94,8 @@ public class SearchFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void updateList() {
|
||||
peerListAdapter.notifyDataSetInvalidated();
|
||||
peerListAdapter.clear();
|
||||
// peerListAdapter.notifyDataSetInvalidated();
|
||||
peerListAdapter.addAll(PeerStore.getInstance().getPeerArrayList());
|
||||
peerListAdapter.notifyDataSetChanged();
|
||||
}
|
||||
@ -96,20 +104,22 @@ public class SearchFragment extends Fragment {
|
||||
updateList();
|
||||
|
||||
String what = intent.getStringExtra("what");
|
||||
Log.d(">>>>>>>>>>>>", "updateUi: " + what);
|
||||
String message = intent.getStringExtra("message");
|
||||
|
||||
if (what == null) {
|
||||
what = "";
|
||||
}
|
||||
|
||||
if (what.equals("connectivity_changed")) {
|
||||
if (what != null && what.equals("connectivity_changed")) {
|
||||
String currentDeviceConnected = intent.getStringExtra("currentDeviceConnected");
|
||||
startNegotiationProtocol(currentDeviceConnected);
|
||||
}
|
||||
|
||||
if (message != null && message.equals("error")) {
|
||||
String snd_message = intent.getStringExtra("snd_message");
|
||||
Snackbar.make(view, snd_message, Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
updateList();
|
||||
}
|
||||
}
|
||||
|
||||
private void startNegotiationProtocol(String macAddress){
|
||||
WifiP2pInfo p2p_info = mService.getP2p_info();
|
||||
WifiP2pInfo p2p_info = getmService().getP2p_info();
|
||||
|
||||
if (p2p_info.isGroupOwner) {
|
||||
startNegotiationProtocolServer(macAddress);
|
||||
@ -120,13 +130,13 @@ public class SearchFragment extends Fragment {
|
||||
|
||||
private void startNegotiationProtocolServer(String macAddress) {
|
||||
// starts the server if necessary
|
||||
WifiP2pInfo p2p_info = mService.getP2p_info();
|
||||
NetworkInfo network_info = mService.getNetwork_info();
|
||||
WifiP2pInfo p2p_info = getmService().getP2p_info();
|
||||
NetworkInfo network_info = getmService().getNetwork_info();
|
||||
|
||||
if (network_info.getState() == NetworkInfo.State.CONNECTED) {
|
||||
if (p2p_info.isGroupOwner) {
|
||||
Log.d(TAG, "You are the group owner");
|
||||
mService.startNegotiationServer(true, macAddress);
|
||||
getmService().startNegotiationServer(true, macAddress);
|
||||
Log.d(TAG, "SocketServer started");
|
||||
}
|
||||
}
|
||||
@ -134,8 +144,8 @@ public class SearchFragment extends Fragment {
|
||||
|
||||
private void startNegotiationProtocolClient(String macAddress){
|
||||
// starts the server if necessary
|
||||
WifiP2pInfo p2p_info = mService.getP2p_info();
|
||||
NetworkInfo network_info = mService.getNetwork_info();
|
||||
WifiP2pInfo p2p_info = getmService().getP2p_info();
|
||||
NetworkInfo network_info = getmService().getNetwork_info();
|
||||
|
||||
if (network_info.getState() == NetworkInfo.State.CONNECTED) {
|
||||
if (!p2p_info.isGroupOwner) {
|
||||
@ -143,40 +153,73 @@ public class SearchFragment extends Fragment {
|
||||
// groupOwnerAddress = p2p_info.groupOwnerAddress;
|
||||
InetAddress groupOwnerAddress = p2p_info.groupOwnerAddress;
|
||||
Log.d(TAG, "Group owner address: " + p2p_info.groupOwnerAddress.getHostAddress());
|
||||
mService.startNegotiationClient(groupOwnerAddress, true, macAddress);
|
||||
getmService().startNegotiationClient(groupOwnerAddress, true, macAddress);
|
||||
Log.d(TAG, "Client Socket started");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (updateUIReceiver != null) {
|
||||
getActivity().unregisterReceiver(updateUIReceiver);
|
||||
updateUIReceiver = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
getActivity().unbindService(mConnection);
|
||||
getActivity().unregisterReceiver(updateUIReceiver);
|
||||
mBound = false;
|
||||
if (updateUIReceiver != null) {
|
||||
getActivity().unregisterReceiver(updateUIReceiver);
|
||||
updateUIReceiver = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
initFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
initFragment();
|
||||
}
|
||||
|
||||
private void initFragment() {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction("com.flashwifi.wifip2p.update_ui");
|
||||
filter.addAction("com.flashwifi.wifip2p.start_roaming");
|
||||
filter.addAction("com.flashwifi.wifip2p.stop_roaming");
|
||||
|
||||
updateUIReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (getActivity() == null) {
|
||||
Log.d(TAG, "onReceive: getActivity is null");
|
||||
return;
|
||||
}
|
||||
Log.d("", "onReceive: FRAGMENT HAT WAS");
|
||||
updateUi(intent);
|
||||
if (intent.getAction().equals("com.flashwifi.wifip2p.start_roaming")) {
|
||||
String mac = intent.getStringExtra("peer_mac_address");
|
||||
ToggleButton toggle = (ToggleButton) getActivity().findViewById(R.id.startSearchButton);
|
||||
toggle.setChecked(false);
|
||||
} else if (intent.getAction().equals("com.flashwifi.wifip2p.stop_roaming")) {
|
||||
PeerStore.getInstance().clear();
|
||||
busy = false;
|
||||
ToggleButton toggle = (ToggleButton) getActivity().findViewById(R.id.startSearchButton);
|
||||
toggle.setChecked(false);
|
||||
} else {
|
||||
updateUi(intent);
|
||||
}
|
||||
}
|
||||
};
|
||||
getActivity().registerReceiver(updateUIReceiver, filter);
|
||||
|
||||
// Bind to Service
|
||||
Intent intent = new Intent(getActivity(), WiFiDirectBroadcastService.class);
|
||||
getActivity().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
|
||||
|
||||
view = getActivity().findViewById(R.id.fragment_view);
|
||||
|
||||
initUI();
|
||||
@ -187,23 +230,24 @@ public class SearchFragment extends Fragment {
|
||||
toolbar.setTitle("Discover Peers");
|
||||
|
||||
final ToggleButton toggle = (ToggleButton) getActivity().findViewById(R.id.startSearchButton);
|
||||
//toggle.setChecked(mService.isInRoleConsumer());
|
||||
|
||||
toggle.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View view) {
|
||||
if (!getmService().isSetup()) {
|
||||
Snackbar.make(view, "Please enable WiFi P2P", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
toggle.setChecked(false);
|
||||
return;
|
||||
}
|
||||
updateList();
|
||||
if (toggle.isChecked()) {
|
||||
if (mBound) {
|
||||
mService.setInRoleHotspot(false);
|
||||
mService.setInRoleConsumer(true);
|
||||
startSearching();
|
||||
}
|
||||
getmService().setInRoleHotspot(false);
|
||||
getmService().setInRoleConsumer(true);
|
||||
startSearching();
|
||||
} else {
|
||||
if (mBound) {
|
||||
mService.setInRoleHotspot(false);
|
||||
mService.setInRoleConsumer(false);
|
||||
stopSearching();
|
||||
}
|
||||
getmService().setInRoleHotspot(false);
|
||||
getmService().setInRoleConsumer(false);
|
||||
stopSearching();
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -223,6 +267,11 @@ public class SearchFragment extends Fragment {
|
||||
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
if (!busy) {
|
||||
busy = true;
|
||||
|
||||
// show progress bar
|
||||
ProgressBar progressConnection = (ProgressBar) getActivity().findViewById(R.id.progressConnection);
|
||||
progressConnection.setVisibility(View.VISIBLE);
|
||||
|
||||
PeerInformation peer = PeerStore.getInstance().getPeerArrayList().get(i);
|
||||
|
||||
peer.setSelected(true);
|
||||
@ -242,13 +291,13 @@ public class SearchFragment extends Fragment {
|
||||
|
||||
|
||||
public void startChat(final String address, String name) {
|
||||
mService.connect(address, new WifiP2pManager.ActionListener() {
|
||||
getmService().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;
|
||||
busy = true;
|
||||
}
|
||||
@Override
|
||||
public void onFailure(int reason) {
|
||||
@ -259,56 +308,31 @@ public class SearchFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void stopSearching() {
|
||||
if (mBound) {
|
||||
mService.stopDiscovery(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Snackbar.make(view, "Stopped search", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
getmService().stopDiscovery(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Snackbar.make(view, "Stopped search", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(int reasonCode) {
|
||||
Snackbar.make(view, "Aaaargh :( problem stopping search!", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void onFailure(int reasonCode) {
|
||||
Snackbar.make(view, "Aaaargh :( problem stopping search!", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void startSearching() {
|
||||
getmService().getPeerList(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Snackbar.make(view, "Successfully searched for peers", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
|
||||
if (mBound) {
|
||||
mService.getPeerList(new WifiP2pManager.ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Snackbar.make(view, "Successfully searched for peers", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
@Override
|
||||
public void onFailure(int reasonCode) {
|
||||
Snackbar.make(view, "Aaaargh :( Peering problem!", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public void onFailure(int reasonCode) {
|
||||
Snackbar.make(view, "Aaaargh :( Peering problem!", Snackbar.LENGTH_LONG).setAction("Action", null).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** Defines callbacks for service binding, passed to bindService() */
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className,
|
||||
IBinder service) {
|
||||
// We've bound to LocalService, cast the IBinder and get LocalService instance
|
||||
WiFiDirectBroadcastService.LocalBinder binder = (WiFiDirectBroadcastService.LocalBinder) service;
|
||||
mService = binder.getService();
|
||||
mBound = true;
|
||||
|
||||
final ToggleButton toggle = (ToggleButton) getActivity().findViewById(R.id.startSearchButton);
|
||||
toggle.setChecked(mService.isInRoleConsumer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName arg0) {
|
||||
mBound = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
286
app/src/main/java/com/flashwifi/wifip2p/SettingsFragment.java
Normal file
@ -0,0 +1,286 @@
|
||||
package com.flashwifi.wifip2p;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.text.InputType;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.flashwifi.wifip2p.iotaAPI.Requests.WalletTestnetTokenGen;
|
||||
import com.pddstudio.preferences.encrypted.EncryptedPreferences;
|
||||
|
||||
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
private String password = "";
|
||||
private String seed = "";
|
||||
|
||||
private static final int TOKEN_TESTNET_RETRIEVE_TASK_COMPLETE = 0;
|
||||
private static final int TOKEN_TESTNET_STATUS_UPDATE = 1;
|
||||
|
||||
private Handler mHandler;
|
||||
private Preference testnetFundAddPref;
|
||||
private Preference prefTestNetPrivate;
|
||||
private PreferenceCategory prefCatIotaSettings;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Bundle bundle = this.getArguments();
|
||||
if (bundle != null) {
|
||||
seed = bundle.getString("seed");
|
||||
}
|
||||
|
||||
// Load the preferences from an XML resource
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
|
||||
// Set version text
|
||||
Preference version = findPreference("pref_key_reset_version");
|
||||
String curTitle = version.getTitle().toString();
|
||||
version.setTitle("Version: "+curTitle);
|
||||
|
||||
prefTestNetPrivate = findPreference("pref_key_switch_testnet_private");
|
||||
prefCatIotaSettings = (PreferenceCategory) findPreference("pref_key_IOTA_settings");
|
||||
|
||||
SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
Boolean testnet = prefManager.getBoolean("pref_key_switch_testnet",false);
|
||||
|
||||
if(!testnet){
|
||||
//Hide the testnet private switch
|
||||
hideTestNetPref();
|
||||
}
|
||||
|
||||
//Set change listener
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.registerOnSharedPreferenceChangeListener(this);
|
||||
|
||||
//Handle post-asynctask activities of updating UI
|
||||
mHandler = new Handler(Looper.getMainLooper()) {
|
||||
@Override
|
||||
public void handleMessage(Message inputMessage) {
|
||||
String result = (String) inputMessage.obj;
|
||||
switch (inputMessage.what) {
|
||||
case TOKEN_TESTNET_STATUS_UPDATE:
|
||||
if(result.equals("Sending")){
|
||||
testnetFundAddPref.setSummary("Sending...");
|
||||
}
|
||||
break;
|
||||
case TOKEN_TESTNET_RETRIEVE_TASK_COMPLETE:
|
||||
if(result.equals("Sent")){
|
||||
makeToastSettingsFragment("2000i generated and added to testnet wallet. Check balance.");
|
||||
testnetFundAddPref.setSummary("2000i added");
|
||||
}
|
||||
else{
|
||||
makeToastSettingsFragment(result);
|
||||
testnetFundAddPref.setSummary(result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if(testnetFundAddPref != null){
|
||||
testnetFundAddPref.setSummary("");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
switch(key){
|
||||
case "pref_key_security":
|
||||
//makeToastSettingsFragment("Security Changed");
|
||||
break;
|
||||
case "pref_key_network_timeout":
|
||||
//makeToastSettingsFragment("Network Timeout Changed");
|
||||
break;
|
||||
case "pref_key_units":
|
||||
makeToastSettingsFragment("Units Changed");
|
||||
//makeToastSettingsFragment("Units Changed");
|
||||
break;
|
||||
case "pref_key_switch_testnet":
|
||||
makeToastSettingsFragment("Testnet on/off Changed");
|
||||
SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
Boolean testnet = prefManager.getBoolean("pref_key_switch_testnet",false);
|
||||
if(testnet){
|
||||
showTestNetPref();
|
||||
}
|
||||
else{
|
||||
hideTestNetPref();
|
||||
}
|
||||
break;
|
||||
case "edit_text_sell_price":
|
||||
makeToastSettingsFragment("Hotspot Sell Price Changed");
|
||||
break;
|
||||
case "edit_text_sell_min_minutes":
|
||||
makeToastSettingsFragment("Hotspot Min sell duration changed");
|
||||
break;
|
||||
case "edit_text_sell_max_minutes":
|
||||
makeToastSettingsFragment("Hotspot Max sell duration changed");
|
||||
break;
|
||||
case "edit_text_buy_price":
|
||||
makeToastSettingsFragment("Buy Price Changed");
|
||||
break;
|
||||
case "edit_text_client_minutes":
|
||||
makeToastSettingsFragment("Client duration duration changed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
|
||||
String key = preference.getKey();
|
||||
|
||||
switch (key) {
|
||||
case "pref_key_reset_data_usage":
|
||||
makeToastSettingsFragment( "Reset Data Usage");
|
||||
break;
|
||||
case "pref_key_testnet_fund_add":
|
||||
SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
Boolean testnet = prefManager.getBoolean("pref_key_switch_testnet",false);
|
||||
|
||||
if(testnet){
|
||||
testnetFundAddPref = preference;
|
||||
testnetFundAddPref.setSummary("Generating...");
|
||||
makeToastSettingsFragment("Testnet wallet token generation request sent.");
|
||||
WalletTestnetTokenGen tokenGen = new WalletTestnetTokenGen(mHandler, getActivity(), getString(R.string.preference_file_key), seed);
|
||||
tokenGen.execute();
|
||||
}
|
||||
else{
|
||||
makeToastSettingsFragment("Please enable testnet first.");
|
||||
}
|
||||
break;
|
||||
case "pref_key_reset_password":
|
||||
makeToastSettingsFragment( "Reset Password");
|
||||
askPassword();
|
||||
break;
|
||||
case "pref_key_reset_wallet":
|
||||
makeToastSettingsFragment("Reset Wallet.");
|
||||
break;
|
||||
}
|
||||
return super.onPreferenceTreeClick(preferenceScreen, preference);
|
||||
}
|
||||
|
||||
private void askPassword() {
|
||||
Context context = getActivity();
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Enter current password");
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
password = input.getText().toString();
|
||||
updatePassword();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
password = "";
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
|
||||
public void updatePassword(){
|
||||
|
||||
if(password.equals("")){
|
||||
//Blank Password
|
||||
makeToastSettingsFragment("Current password cannot be blank.");
|
||||
return;
|
||||
}
|
||||
|
||||
Context context = getActivity();
|
||||
EncryptedPreferences encryptedPreferences = new EncryptedPreferences.Builder(context).withEncryptionPassword(password).build();
|
||||
String seed = encryptedPreferences.getString(getString(R.string.encrypted_seed), null);
|
||||
|
||||
if (seed != null && context != null) {
|
||||
//Correct password, re-store seed with new input password
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle("Enter new password");
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
String newPassword = input.getText().toString();
|
||||
if(!newPassword.equals("")){
|
||||
EncryptedPreferences encryptedPreferencesRemove = new EncryptedPreferences.Builder(context).withEncryptionPassword(password).build();
|
||||
encryptedPreferencesRemove.edit().remove(getString(R.string.encrypted_seed)).apply();
|
||||
|
||||
EncryptedPreferences encryptedPreferencesUpdated = new EncryptedPreferences.Builder(context).withEncryptionPassword(newPassword).build();
|
||||
encryptedPreferencesUpdated.edit().putString(getString(R.string.encrypted_seed), seed).apply();
|
||||
password = "";
|
||||
makeToastSettingsFragment("Password changed.");
|
||||
}
|
||||
else{
|
||||
password = "";
|
||||
makeToastSettingsFragment("New password cannot be blank.");
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
password = "";
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
else{
|
||||
//Wrong Password
|
||||
makeToastSettingsFragment("Wrong Password. Please try again.");
|
||||
}
|
||||
}
|
||||
|
||||
private void makeToastSettingsFragment(String s) {
|
||||
if(getActivity() != null){
|
||||
Toast.makeText(getActivity(), s, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void hidePreference(String prefKey, String catKey){
|
||||
Preference pref = findPreference(prefKey);
|
||||
PreferenceCategory catPref = (PreferenceCategory) findPreference(catKey);
|
||||
catPref.removePreference(pref);
|
||||
}
|
||||
|
||||
private void showPreference(String prefKey, String catKey){
|
||||
Preference pref = findPreference(prefKey);
|
||||
PreferenceCategory catPref = (PreferenceCategory) findPreference(catKey);
|
||||
catPref.addPreference(pref);
|
||||
}
|
||||
|
||||
private void hideTestNetPref() {
|
||||
prefCatIotaSettings.removePreference(prefTestNetPrivate);
|
||||
}
|
||||
|
||||
private void showTestNetPref() {
|
||||
prefCatIotaSettings.addPreference(prefTestNetPrivate);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -20,7 +20,7 @@ import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.flashwifi.wifip2p.iotaAPI.Requests.WalletAddressAndBalanceChecker;
|
||||
import com.flashwifi.wifip2p.iotaAPI.Requests.WalletBalanceChecker;
|
||||
import com.flashwifi.wifip2p.iotaAPI.Requests.WalletTransferRequest;
|
||||
|
||||
import jota.error.ArgumentException;
|
||||
@ -47,7 +47,7 @@ public class WithdrawWalletFragment extends Fragment {
|
||||
private EditText editTextAmount;
|
||||
private EditText editTextMessage;
|
||||
private EditText editTextTag;
|
||||
private WalletAddressAndBalanceChecker addressAndBalanceChecker;
|
||||
private WalletBalanceChecker addressAndBalanceChecker;
|
||||
|
||||
private GifImageView loadingGifImageView;
|
||||
private SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
@ -94,22 +94,22 @@ public class WithdrawWalletFragment extends Fragment {
|
||||
hideLoadingGIF();
|
||||
transactionInProgress = false;
|
||||
|
||||
if(returnStatus == "noError"){
|
||||
balanceTextView.setText(appWalletBalance + " i");
|
||||
if(returnStatus.equals("noError")){
|
||||
balanceTextView.setText(appWalletBalance);
|
||||
makeToastFundWalletFragment("Balance updated");
|
||||
}
|
||||
else if (returnStatus == "noErrorNoUpdateMessage"){
|
||||
balanceTextView.setText(appWalletBalance + " i");
|
||||
else if (returnStatus.equals("noErrorNoUpdateMessage")){
|
||||
balanceTextView.setText(appWalletBalance);
|
||||
clearAllTransferValues();
|
||||
makeFieldsEditable();
|
||||
}
|
||||
else if (returnStatus == "hostError"){
|
||||
else if (returnStatus.equals("hostError")){
|
||||
makeToastFundWalletFragment("Unable to reach host (node)");
|
||||
}
|
||||
else if (returnStatus == "addressError"){
|
||||
else if (returnStatus.equals("addressError")){
|
||||
makeToastFundWalletFragment("Error getting address");
|
||||
}
|
||||
else if (returnStatus == "balanceError"){
|
||||
else if (returnStatus.equals("balanceError")){
|
||||
makeToastFundWalletFragment("Error getting balance");
|
||||
}
|
||||
else{
|
||||
@ -198,7 +198,7 @@ public class WithdrawWalletFragment extends Fragment {
|
||||
|
||||
private void getBalance(Boolean updateMessage) {
|
||||
transactionInProgress = true;
|
||||
addressAndBalanceChecker = new WalletAddressAndBalanceChecker(getActivity(),getActivity().getString(R.string.preference_file_key),appWalletSeed, mHandler,WITHDRAW_WALLET,updateMessage);
|
||||
addressAndBalanceChecker = new WalletBalanceChecker(getActivity(),getActivity().getString(R.string.preference_file_key),appWalletSeed, mHandler,WITHDRAW_WALLET,updateMessage);
|
||||
addressAndBalanceChecker.execute();
|
||||
}
|
||||
|
||||
|
||||
@ -86,17 +86,20 @@ public class AccessPointTask extends AsyncTask<Object, Void, String> {
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
sendUpdateUIBroadcastWithMessage("AP FAILED");
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
sendUpdateUIBroadcastWithMessage("AP FAILED");
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
sendUpdateUIBroadcastWithMessage("AP FAILED");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!methodFound){
|
||||
// ToDo: implement this
|
||||
sendUpdateUIBroadcastWithMessage("AP FAILED");
|
||||
//statusView.setText("Your phone's API does not contain setWifiApEnabled method to configure an access point");
|
||||
}
|
||||
|
||||
|
||||
@ -8,15 +8,21 @@ public class Accountant {
|
||||
|
||||
|
||||
private ArrayList<Bill> bills;
|
||||
private int totalMegabytes;
|
||||
private int totalBytes;
|
||||
private int totalIotaPrice;
|
||||
private int totalDurance;
|
||||
private int bookedMegabytes;
|
||||
private int bookedMinutes;
|
||||
private int totalIotaDeposit;
|
||||
private int timeoutMinutes;
|
||||
private int iotaPerMegaByte;
|
||||
private boolean closeAfterwards;
|
||||
private long startTime;
|
||||
|
||||
private FlashChannelHelper flashChannelHelper;
|
||||
|
||||
private boolean closed = true;
|
||||
private String seed;
|
||||
|
||||
public static Accountant getInstance() {
|
||||
return ourInstance;
|
||||
@ -25,19 +31,49 @@ public class Accountant {
|
||||
private Accountant() {
|
||||
}
|
||||
|
||||
public void start(int bookedMegabytes, int timeoutMinutes){
|
||||
if (closed) {
|
||||
bills = new ArrayList<Bill>();
|
||||
this.bookedMegabytes = bookedMegabytes;
|
||||
this.timeoutMinutes = timeoutMinutes;
|
||||
totalMegabytes = 0;
|
||||
totalIotaPrice = 0;
|
||||
totalDurance = 0;
|
||||
flashChannelHelper = new FlashChannelHelper();
|
||||
closed = false;
|
||||
public void start(int bookedMegabytes, int timeoutMinutes, int bookedMinutes, int totalIotaDeposit, int iotaPerMegaByte){
|
||||
bills = new ArrayList<Bill>();
|
||||
this.bookedMegabytes = bookedMegabytes;
|
||||
this.timeoutMinutes = timeoutMinutes;
|
||||
this.totalIotaDeposit = totalIotaDeposit;
|
||||
this.iotaPerMegaByte = iotaPerMegaByte;
|
||||
totalBytes = 0;
|
||||
totalIotaPrice = 0;
|
||||
totalDurance = 0;
|
||||
flashChannelHelper = new FlashChannelHelper();
|
||||
closeAfterwards = false;
|
||||
startTime = System.currentTimeMillis() / 1000L;
|
||||
this.bookedMinutes = bookedMinutes;
|
||||
closed = false;
|
||||
}
|
||||
|
||||
public long getLastTime() {
|
||||
if (bills.isEmpty()) {
|
||||
return startTime;
|
||||
} else {
|
||||
return bills.get(bills.size()-1).getTime();
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.bookedMegabytes = 0;
|
||||
this.timeoutMinutes = 0;
|
||||
this.totalIotaDeposit = 0;
|
||||
this.iotaPerMegaByte = 0;
|
||||
totalBytes = 0;
|
||||
totalIotaPrice = 0;
|
||||
totalDurance = 0;
|
||||
bookedMinutes = 0;
|
||||
}
|
||||
|
||||
public boolean isCloseAfterwards() {
|
||||
return closeAfterwards;
|
||||
}
|
||||
|
||||
public void setCloseAfterwards(boolean closeAfterwards) {
|
||||
this.closeAfterwards = closeAfterwards;
|
||||
}
|
||||
|
||||
public int getNextBillNumber() {
|
||||
return bills.size() + 1;
|
||||
}
|
||||
@ -54,22 +90,25 @@ public class Accountant {
|
||||
|
||||
// ToDo: check bill
|
||||
|
||||
totalMegabytes += b.getMegabytesUsed();
|
||||
totalBytes += b.getBytesUsed();
|
||||
totalIotaPrice += b.getPriceInIota();
|
||||
totalDurance += b.getDuranceInMinutes();
|
||||
totalDurance += b.getDuranceInSeconds();
|
||||
|
||||
// ToDo: apply transfer to flash channel
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Bill createBill(int megaByte, int priceInIota, int duranceMinutes){
|
||||
public Bill createBill(int bytes){
|
||||
if (!closed) {
|
||||
Bill b = new Bill(getNextBillNumber(), totalDurance, duranceMinutes, megaByte, priceInIota);
|
||||
long now = System.currentTimeMillis() / 1000L;
|
||||
long duranceInSeconds = now - getLastTime();
|
||||
int priceInIota = (int) (bytes * getIotaPerByte());
|
||||
Bill b = new Bill(getNextBillNumber(), now, duranceInSeconds, bytes, priceInIota);
|
||||
|
||||
totalMegabytes += megaByte;
|
||||
totalBytes += bytes;
|
||||
totalIotaPrice += priceInIota;
|
||||
totalDurance += duranceMinutes;
|
||||
totalDurance += duranceInSeconds;
|
||||
|
||||
// 1) modify flash channel
|
||||
applyTransferToFlashChannel(priceInIota);
|
||||
@ -100,7 +139,11 @@ public class Accountant {
|
||||
}
|
||||
|
||||
public int getTotalMegabytes() {
|
||||
return totalMegabytes;
|
||||
return totalBytes / (1024*1024);
|
||||
}
|
||||
|
||||
public int getTotalBytes() {
|
||||
return totalBytes / (1024*1024);
|
||||
}
|
||||
|
||||
public int getTotalIotaPrice() {
|
||||
@ -114,4 +157,36 @@ public class Accountant {
|
||||
public int getBookedMegabytes() {
|
||||
return bookedMegabytes;
|
||||
}
|
||||
|
||||
public int getBookedBytes() {
|
||||
return bookedMegabytes;
|
||||
}
|
||||
|
||||
public int getTimeoutMinutes() {
|
||||
return timeoutMinutes;
|
||||
}
|
||||
|
||||
public int getBookedMinutes() {
|
||||
return bookedMinutes;
|
||||
}
|
||||
|
||||
public int getTotalIotaDeposit() {
|
||||
return totalIotaDeposit;
|
||||
}
|
||||
|
||||
public int getIotaPerMegaByte() {
|
||||
return iotaPerMegaByte;
|
||||
}
|
||||
|
||||
public double getIotaPerByte() {
|
||||
return ((double)getIotaPerMegaByte()) / (1024.0d * 1024.0d);
|
||||
}
|
||||
|
||||
public void setSeed(String seed) {
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
public String getSeed() {
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,18 +3,18 @@ package com.flashwifi.wifip2p.billing;
|
||||
|
||||
public class Bill {
|
||||
private int index;
|
||||
private int minuteStart;
|
||||
private int duranceInMinutes = 1;
|
||||
private int megabytesUsed;
|
||||
private int bytesUsed;
|
||||
private int priceInIota;
|
||||
private long duranceInSeconds;
|
||||
private long time;
|
||||
|
||||
private boolean acceptedByPeer;
|
||||
|
||||
public Bill(int index, int minuteStart, int duranceInMinutes, int megabytesUsed, int priceInIota) {
|
||||
public Bill(int index, long time, long duranceInSeconds, int bytesUsed, int priceInIota) {
|
||||
this.index = index;
|
||||
this.minuteStart = minuteStart;
|
||||
this.duranceInMinutes = duranceInMinutes;
|
||||
this.megabytesUsed = megabytesUsed;
|
||||
this.time = time;
|
||||
this.duranceInSeconds = duranceInSeconds;
|
||||
this.bytesUsed = bytesUsed;
|
||||
this.priceInIota = priceInIota;
|
||||
}
|
||||
|
||||
@ -30,19 +30,24 @@ public class Bill {
|
||||
return index;
|
||||
}
|
||||
|
||||
public int getMinuteStart() {
|
||||
return minuteStart;
|
||||
}
|
||||
|
||||
public int getDuranceInMinutes() {
|
||||
return duranceInMinutes;
|
||||
return (int) duranceInSeconds/60;
|
||||
}
|
||||
|
||||
public int getMegabytesUsed() {
|
||||
return megabytesUsed;
|
||||
public int getDuranceInSeconds() {
|
||||
return (int) duranceInSeconds;
|
||||
}
|
||||
|
||||
public int getBytesUsed() {
|
||||
return bytesUsed;
|
||||
}
|
||||
|
||||
public int getPriceInIota() {
|
||||
return priceInIota;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
package com.flashwifi.wifip2p.billing;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import com.flashwifi.wifip2p.datastore.PeerInformation;
|
||||
import com.flashwifi.wifip2p.datastore.PeerStore;
|
||||
import com.flashwifi.wifip2p.negotiation.SocketWrapper;
|
||||
import com.flashwifi.wifip2p.protocol.BillMessage;
|
||||
import com.flashwifi.wifip2p.protocol.BillMessageAnswer;
|
||||
@ -11,6 +14,9 @@ import com.flashwifi.wifip2p.protocol.BillingCloseChannel;
|
||||
import com.flashwifi.wifip2p.protocol.BillingCloseChannelAnswer;
|
||||
import com.flashwifi.wifip2p.protocol.BillingOpenChannel;
|
||||
import com.flashwifi.wifip2p.protocol.BillingOpenChannelAnswer;
|
||||
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;
|
||||
|
||||
@ -30,11 +36,13 @@ import java.net.UnknownHostException;
|
||||
public class BillingClient {
|
||||
private static final String TAG = "BillingClient";
|
||||
private final Gson gson;
|
||||
private final String mac;
|
||||
private State state = State.NOT_PAIRED;
|
||||
private Socket socket;
|
||||
private SocketWrapper socketWrapper;
|
||||
private static final int PORT = 9199;
|
||||
private static final int clientTimeoutMillis = 2 * 60 * 1000;
|
||||
private static final int maxErrorCount = 5;
|
||||
|
||||
private BillingOpenChannel billingOpenChannel;
|
||||
private BillingOpenChannelAnswer billingOpenChannelAnswer;
|
||||
@ -49,15 +57,18 @@ public class BillingClient {
|
||||
context.sendBroadcast(local);
|
||||
}
|
||||
|
||||
public BillingClient(Context context){
|
||||
public BillingClient(String mac, Context context){
|
||||
this.context = context;
|
||||
this.mac = mac;
|
||||
gson = new GsonBuilder().create();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void start(String serverIPAddress) {
|
||||
while (state != State.CLOSED) {
|
||||
int error_count = 0;
|
||||
|
||||
while (state != State.CLOSED && state != State.ERROR) {
|
||||
try {
|
||||
// create client socket that connects to server
|
||||
socket = new Socket(serverIPAddress, PORT);
|
||||
@ -74,17 +85,39 @@ public class BillingClient {
|
||||
String hotspotStateLine = socketWrapper.getLineThrowing();
|
||||
if (hotspotStateLine.contains("INITIAL") || hotspotStateLine.contains("NOT_PAIRED")) {
|
||||
// ask the hotspot to open the flash channel
|
||||
|
||||
// get the negotiated data
|
||||
NegotiationOffer offer = PeerStore.getInstance().getLatestNegotiationOffer(mac);
|
||||
NegotiationOfferAnswer answer = PeerStore.getInstance().getLatestNegotiationOfferAnswer(mac);
|
||||
NegotiationFinalization finalization = PeerStore.getInstance().getLatestFinalization(mac);
|
||||
// get the necessary values
|
||||
// ToDo: replace magic number with setting
|
||||
int totalMegabytes = 100;
|
||||
int treeDepth = 8;
|
||||
String[] digests = new String[]{"1234", "2345", "3456"};
|
||||
billingOpenChannel = new BillingOpenChannel(100, 100, "clientAddress", 8, digests, 20 * 60 * 1000);
|
||||
int timeoutMinutesClient = 20 * 60 * 1000;
|
||||
|
||||
int iotaPerMegabyte = offer.getIotaPerMegabyte();
|
||||
String clientRefundAddress = finalization.getClientRefundAddress();
|
||||
int totalMinutes = answer.getDuranceInMinutes();
|
||||
|
||||
billingOpenChannel = new BillingOpenChannel(totalMegabytes, iotaPerMegabyte, clientRefundAddress, treeDepth, digests, timeoutMinutesClient, totalMinutes);
|
||||
PeerStore.getInstance().setLatestBillingOpenChannel(mac, billingOpenChannel);
|
||||
String billingOpenChannelString = gson.toJson(billingOpenChannel);
|
||||
socketWrapper.sendLine(billingOpenChannelString);
|
||||
// receive the hotspot details for the flash channel
|
||||
String billingOpenChannelAnswerString = socketWrapper.getLineThrowing();
|
||||
billingOpenChannelAnswer = gson.fromJson(billingOpenChannelAnswerString, BillingOpenChannelAnswer.class);
|
||||
PeerStore.getInstance().setLatestBillingOpenChannelAnswer(mac, billingOpenChannelAnswer);
|
||||
// now create the flash channel on our side
|
||||
Accountant.getInstance().start(billingOpenChannel.getTotalMegabytes(), billingOpenChannel.getTimeoutMinutesClient());
|
||||
Accountant.getInstance().start(billingOpenChannel.getTotalMegabytes(), billingOpenChannel.getTimeoutMinutesClient(), billingOpenChannel.getTotalMinutes(), billingOpenChannelAnswer.getClientDepositIota(),
|
||||
billingOpenChannel.getIotaPerMegabyte());
|
||||
sendUpdateUIBroadcastWithMessage("Channel established");
|
||||
state = State.ROAMING;
|
||||
|
||||
// start the task to fund the channel
|
||||
sendUpdateUIBroadcastWithMessage("Start Channel funding");
|
||||
|
||||
} else {
|
||||
// what to do if the hotspot already created stuff and was in roaming mode
|
||||
// ToDo: ^^^^^
|
||||
@ -106,7 +139,7 @@ public class BillingClient {
|
||||
// ToDo: flash object -> diff()
|
||||
// ToDo: sign flash transaction
|
||||
sendUpdateUIBroadcastWithMessage("Billing");
|
||||
latestBillAnswer = new BillMessageAnswer("id", true, "", false);
|
||||
latestBillAnswer = new BillMessageAnswer("id", true, "", Accountant.getInstance().isCloseAfterwards());
|
||||
latestBillAnswerString = gson.toJson(latestBillAnswer);
|
||||
socketWrapper.sendLine(latestBillAnswerString);
|
||||
|
||||
@ -128,16 +161,47 @@ public class BillingClient {
|
||||
String billingCloseChannelAnswerString = gson.toJson(billingCloseChannelAnswer);
|
||||
socketWrapper.sendLine(billingCloseChannelAnswerString);
|
||||
|
||||
sendUpdateUIBroadcastWithMessage("Channel closed");
|
||||
|
||||
state = State.CLOSED;
|
||||
}
|
||||
|
||||
|
||||
} catch (SocketException e) {
|
||||
e.printStackTrace();
|
||||
sendUpdateUIBroadcastWithMessage("Socket exception");
|
||||
error_count++;
|
||||
} catch (UnknownHostException e) {
|
||||
sendUpdateUIBroadcastWithMessage("UnknownHostException exception");
|
||||
e.printStackTrace();
|
||||
error_count++;
|
||||
} catch (IOException e) {
|
||||
sendUpdateUIBroadcastWithMessage("IOException");
|
||||
e.printStackTrace();
|
||||
error_count++;
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
try {
|
||||
socketWrapper.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// sleep in finally case 5 seconds
|
||||
try {
|
||||
Thread.sleep(1000*5);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (error_count >= maxErrorCount) {
|
||||
// stop trying to connect
|
||||
Log.d(TAG, "start: error count too high");
|
||||
state = State.ERROR;
|
||||
sendUpdateUIBroadcastWithMessage("Exit");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -146,6 +210,7 @@ public class BillingClient {
|
||||
NOT_PAIRED,
|
||||
ROAMING,
|
||||
CLOSE,
|
||||
CLOSED
|
||||
CLOSED,
|
||||
ERROR
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,16 @@
|
||||
package com.flashwifi.wifip2p.billing;
|
||||
|
||||
import android.app.usage.NetworkStats;
|
||||
import android.app.usage.NetworkStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.RemoteException;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.Log;
|
||||
|
||||
import com.flashwifi.wifip2p.datastore.PeerStore;
|
||||
import com.flashwifi.wifip2p.negotiation.SocketWrapper;
|
||||
import com.flashwifi.wifip2p.protocol.BillMessage;
|
||||
import com.flashwifi.wifip2p.protocol.BillMessageAnswer;
|
||||
@ -11,15 +18,21 @@ import com.flashwifi.wifip2p.protocol.BillingCloseChannel;
|
||||
import com.flashwifi.wifip2p.protocol.BillingCloseChannelAnswer;
|
||||
import com.flashwifi.wifip2p.protocol.BillingOpenChannel;
|
||||
import com.flashwifi.wifip2p.protocol.BillingOpenChannelAnswer;
|
||||
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.math.BigDecimal;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import static android.content.Context.WIFI_SERVICE;
|
||||
|
||||
/**
|
||||
* 1) This class keeps the socket connection alive.
|
||||
* 2) It tracks the state of the communication.
|
||||
@ -32,6 +45,10 @@ import java.net.UnknownHostException;
|
||||
public class BillingServer {
|
||||
private static final String TAG = "BillingServer";
|
||||
private final Gson gson;
|
||||
private final String mac;
|
||||
private final String hotspotRefundAddress;
|
||||
private final String channelRootAddress;
|
||||
private final String[] digests;
|
||||
private State state = State.NOT_PAIRED;
|
||||
private ServerSocket serverSocket;
|
||||
private Socket socket;
|
||||
@ -40,6 +57,7 @@ public class BillingServer {
|
||||
private static final int serverTimeoutMillis = 2 * 60 * 1000;
|
||||
|
||||
Context context;
|
||||
NetworkStatsManager networkStatsManager;
|
||||
|
||||
private void sendUpdateUIBroadcastWithMessage(String message){
|
||||
Intent local = new Intent();
|
||||
@ -48,10 +66,33 @@ public class BillingServer {
|
||||
context.sendBroadcast(local);
|
||||
}
|
||||
|
||||
public BillingServer(int bookedMegabytes, int timeoutMinutes, Context context){
|
||||
public BillingServer(String mac, Context context){
|
||||
this.context = context;
|
||||
Accountant.getInstance().start(bookedMegabytes,timeoutMinutes);
|
||||
this.mac = mac;
|
||||
|
||||
// get the negotiated data
|
||||
NegotiationOffer offer = PeerStore.getInstance().getLatestNegotiationOffer(mac);
|
||||
NegotiationOfferAnswer answer = PeerStore.getInstance().getLatestNegotiationOfferAnswer(mac);
|
||||
NegotiationFinalization finalization = PeerStore.getInstance().getLatestFinalization(mac);
|
||||
// get the necessary values
|
||||
// ToDo: replace magic number with setting
|
||||
int totalMegabytes = 100;
|
||||
int treeDepth = 8;
|
||||
this.digests = new String[]{"1234", "2345", "3456"};
|
||||
int timeoutMinutesServer = 20 * 60 * 1000;
|
||||
|
||||
this.hotspotRefundAddress = finalization.getHotspotRefundAddress();
|
||||
this.channelRootAddress = finalization.getDepositAddressFlashChannel();
|
||||
|
||||
|
||||
int iotaPerMegabyte = offer.getIotaPerMegabyte();
|
||||
int iotaDepositClient = totalMegabytes * iotaPerMegabyte;
|
||||
String clientRefundAddress = finalization.getClientRefundAddress();
|
||||
int totalMinutes = answer.getDuranceInMinutes();
|
||||
|
||||
Accountant.getInstance().start(totalMegabytes, timeoutMinutesServer, totalMinutes, iotaDepositClient, iotaPerMegabyte);
|
||||
gson = new GsonBuilder().create();
|
||||
networkStatsManager = (NetworkStatsManager) context.getSystemService(Context.NETWORK_STATS_SERVICE);
|
||||
}
|
||||
|
||||
public void start() throws IOException {
|
||||
@ -59,6 +100,10 @@ public class BillingServer {
|
||||
createDeadlineGuard();
|
||||
// 1) create a socket
|
||||
|
||||
Log.d(TAG, "start: Billing server has been started");
|
||||
|
||||
// ToDo: receive end of roaming broadcast
|
||||
|
||||
while (state != State.CLOSED) {
|
||||
try {
|
||||
// create server socket
|
||||
@ -86,11 +131,20 @@ public class BillingServer {
|
||||
// receive the BillingOpenChannel message
|
||||
String billingOpenChannelString = socketWrapper.getLineThrowing();
|
||||
BillingOpenChannel billingOpenChannel = gson.fromJson(billingOpenChannelString, BillingOpenChannel.class);
|
||||
|
||||
PeerStore.getInstance().setLatestBillingOpenChannel(mac, billingOpenChannel);
|
||||
// answer with billingOpenChannelAnswerString
|
||||
|
||||
|
||||
// ToDo: create the flash channel
|
||||
String[] myDigests = new String[]{"1234", "2345", "3456"};
|
||||
BillingOpenChannelAnswer billingOpenChannelAnswer = new BillingOpenChannelAnswer(0, 0, "", "", myDigests);
|
||||
|
||||
|
||||
BillingOpenChannelAnswer billingOpenChannelAnswer = new BillingOpenChannelAnswer(
|
||||
Accountant.getInstance().getTotalIotaDeposit(),
|
||||
Accountant.getInstance().getTotalIotaDeposit(),
|
||||
hotspotRefundAddress,
|
||||
channelRootAddress,
|
||||
digests);
|
||||
PeerStore.getInstance().setLatestBillingOpenChannelAnswer(mac, billingOpenChannelAnswer);
|
||||
String billingOpenChannelAnswerString = gson.toJson(billingOpenChannelAnswer);
|
||||
socketWrapper.sendLine(billingOpenChannelAnswerString);
|
||||
|
||||
@ -98,6 +152,9 @@ public class BillingServer {
|
||||
|
||||
// OK
|
||||
state = State.ROAMING;
|
||||
|
||||
// start funding
|
||||
sendUpdateUIBroadcastWithMessage("Start Channel funding");
|
||||
}
|
||||
|
||||
if (state == State.ROAMING) {
|
||||
@ -117,10 +174,23 @@ public class BillingServer {
|
||||
Log.d(TAG, "start: Good morning!");
|
||||
// create new bill
|
||||
// ToDo: integrate real network data
|
||||
// ToDo: calculate time correctly
|
||||
b = Accountant.getInstance().createBill(0,0,1);
|
||||
NetworkStats.Bucket bucket;
|
||||
long total_bytes;
|
||||
try {
|
||||
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI,
|
||||
"",
|
||||
Accountant.getInstance().getLastTime() * 1000,
|
||||
System.currentTimeMillis());
|
||||
long bytes_received = bucket.getRxBytes();
|
||||
long bytes_transmitted = bucket.getTxBytes();
|
||||
total_bytes = bytes_received + bytes_transmitted;
|
||||
} catch (RemoteException e) {
|
||||
Log.d(TAG, "start: Can't get the network traffic.");
|
||||
total_bytes = 0;
|
||||
}
|
||||
b = Accountant.getInstance().createBill((int)total_bytes);
|
||||
// ToDo: integrate real flash channel
|
||||
latestBill = new BillMessage(b, "", false);
|
||||
latestBill = new BillMessage(b, "<flash obj>", Accountant.getInstance().isCloseAfterwards());
|
||||
latestBillString = gson.toJson(latestBill);
|
||||
socketWrapper.sendLine(latestBillString);
|
||||
|
||||
@ -136,11 +206,14 @@ public class BillingServer {
|
||||
if (latestBill.isCloseAfterwards() || latestBillAnswer.isCloseAfterwards()) {
|
||||
state = State.CLOSE;
|
||||
}
|
||||
|
||||
sendUpdateUIBroadcastWithMessage("Billing");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (state == State.CLOSE) {
|
||||
Log.d(TAG, "start: state is CLOSE now");
|
||||
// ToDo: handle the final deposit of the flash channel
|
||||
// ToDo: sign the transaction
|
||||
BillingCloseChannel billingCloseChannel = new BillingCloseChannel(0,0,0,0,"", "", "");
|
||||
@ -150,6 +223,9 @@ public class BillingServer {
|
||||
String billingCloseChannelAnswerString = socketWrapper.getLineThrowing();
|
||||
BillingCloseChannelAnswer billingCloseChannelAnswer = gson.fromJson(billingCloseChannelAnswerString, BillingCloseChannelAnswer.class);
|
||||
// ToDo: validate the signature
|
||||
|
||||
// change the ui
|
||||
sendUpdateUIBroadcastWithMessage("Channel closed");
|
||||
state = State.CLOSED;
|
||||
}
|
||||
|
||||
@ -158,18 +234,35 @@ public class BillingServer {
|
||||
boolean attached = false;
|
||||
while (!attached) {
|
||||
Log.d(TAG, "start: Attach to tangle please");
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
state = State.FULLY_ATTACHED;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (socketWrapper != null) {
|
||||
socketWrapper.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
try {
|
||||
if (serverSocket != null) {
|
||||
serverSocket.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void createDeadlineGuard() {
|
||||
// this method measures the time and stops the connection if
|
||||
// nothing happened after <timeoutMinutes>
|
||||
|
||||
@ -1,9 +1,16 @@
|
||||
package com.flashwifi.wifip2p.broadcast;
|
||||
import android.app.Activity;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.DhcpInfo;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.net.wifi.p2p.WifiP2pConfig;
|
||||
@ -13,26 +20,52 @@ import android.net.wifi.p2p.WifiP2pInfo;
|
||||
import android.net.wifi.p2p.WifiP2pManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.Log;
|
||||
|
||||
import com.flashwifi.wifip2p.AddressBalanceTransfer;
|
||||
import com.flashwifi.wifip2p.Constants;
|
||||
import com.flashwifi.wifip2p.MainActivity;
|
||||
import com.flashwifi.wifip2p.R;
|
||||
import com.flashwifi.wifip2p.accesspoint.AccessPointTask;
|
||||
import com.flashwifi.wifip2p.accesspoint.ConnectTask;
|
||||
import com.flashwifi.wifip2p.accesspoint.StopAccessPointTask;
|
||||
import com.flashwifi.wifip2p.billing.Accountant;
|
||||
import com.flashwifi.wifip2p.billing.BillingClient;
|
||||
import com.flashwifi.wifip2p.billing.BillingServer;
|
||||
import com.flashwifi.wifip2p.datastore.PeerStore;
|
||||
import com.flashwifi.wifip2p.iotaAPI.Requests.WalletTransferRequest;
|
||||
import com.flashwifi.wifip2p.negotiation.Negotiator;
|
||||
import com.flashwifi.wifip2p.protocol.BillingOpenChannel;
|
||||
import com.flashwifi.wifip2p.protocol.BillingOpenChannelAnswer;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationFinalization;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOffer;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOfferAnswer;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import jota.IotaAPI;
|
||||
import jota.dto.response.GetBalancesResponse;
|
||||
import jota.dto.response.SendTransferResponse;
|
||||
import jota.error.ArgumentException;
|
||||
import jota.model.Transfer;
|
||||
|
||||
public class WiFiDirectBroadcastService extends Service {
|
||||
public final static String TAG = "WiFiService";
|
||||
|
||||
@ -75,6 +108,62 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
AccessPointTask apTask;
|
||||
boolean apRuns = false;
|
||||
ConnectTask connectTask;
|
||||
private boolean negotiatorRunning = false;
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
|
||||
Log.i(TAG, "Received Start Foreground Intent ");
|
||||
Intent notificationIntent = new Intent(this, MainActivity.class);
|
||||
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
|
||||
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
|
||||
notificationIntent, 0);
|
||||
/*
|
||||
Intent previousIntent = new Intent(this, WiFiDirectBroadcastService.class);
|
||||
previousIntent.setAction(Constants.ACTION.PREV_ACTION);
|
||||
PendingIntent ppreviousIntent = PendingIntent.getService(this, 0,
|
||||
previousIntent, 0);
|
||||
|
||||
Intent playIntent = new Intent(this, WiFiDirectBroadcastService.class);
|
||||
playIntent.setAction(Constants.ACTION.PLAY_ACTION);
|
||||
PendingIntent pplayIntent = PendingIntent.getService(this, 0,
|
||||
playIntent, 0);*/
|
||||
|
||||
Intent stopIntent = new Intent(this, WiFiDirectBroadcastService.class);
|
||||
stopIntent.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
|
||||
PendingIntent pstopIntent = PendingIntent.getService(this, 0,
|
||||
stopIntent, 0);
|
||||
|
||||
Bitmap icon = BitmapFactory.decodeResource(getResources(),
|
||||
R.drawable.icon_tethering_on);
|
||||
|
||||
Notification notification = new NotificationCompat.Builder(this)
|
||||
.setContentTitle(getString(R.string.app_name))
|
||||
.setTicker(getString(R.string.app_name))
|
||||
.setContentText(getString(R.string.notification_doing_nothing))
|
||||
.setSmallIcon(R.drawable.icon_tethering_on)
|
||||
.setLargeIcon(
|
||||
Bitmap.createScaledBitmap(icon, 128, 128, false))
|
||||
.setContentIntent(pendingIntent)
|
||||
.setOngoing(true)
|
||||
.addAction(R.drawable.icon_tethering_off, "Stop",
|
||||
pstopIntent).build();
|
||||
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
|
||||
notification);
|
||||
} else if (intent.getAction().equals(
|
||||
Constants.ACTION.STOPFOREGROUND_ACTION)) {
|
||||
Log.i(TAG, "Received Stop Foreground Intent");
|
||||
stopForeground(true);
|
||||
stopSelf();
|
||||
}
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
public boolean isSetup() {
|
||||
return setup;
|
||||
}
|
||||
|
||||
public void enableWiFi() {
|
||||
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
|
||||
@ -94,15 +183,21 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
public void startBillingServer(){
|
||||
public void resetBillingState() {
|
||||
billingClientIsRunning = false;
|
||||
billingServerIsRunning = false;
|
||||
}
|
||||
|
||||
public void startBillingServer(String mac){
|
||||
if (!billingServerIsRunning) {
|
||||
billingServerIsRunning = true;
|
||||
|
||||
Runnable task = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(TAG, "run: instantiate billing server");
|
||||
// ToDo: remove magic numbers
|
||||
BillingServer billingServer = new BillingServer(100, 20, getApplicationContext());
|
||||
BillingServer billingServer = new BillingServer(mac, getApplicationContext());
|
||||
|
||||
try {
|
||||
billingServer.start();
|
||||
@ -115,13 +210,17 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
};
|
||||
Log.d(TAG, "startBillingServer");
|
||||
Thread thread = new Thread(task);
|
||||
//asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
|
||||
//AsyncTask.execute(thread);
|
||||
threads.add(thread);
|
||||
AsyncTask.execute(thread);
|
||||
thread.start();
|
||||
} else {
|
||||
Log.d(TAG, "startBillingServer: blocked");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void startBillingClient() {
|
||||
public void startBillingClient(String mac) {
|
||||
if (!billingClientIsRunning) {
|
||||
billingClientIsRunning = true;
|
||||
|
||||
@ -130,18 +229,34 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
Runnable task = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// ToDo: remove magic numbers
|
||||
BillingClient billingClient = new BillingClient(getApplicationContext());
|
||||
// ToDo: get the AP gateway ip address
|
||||
BillingClient billingClient = new BillingClient(mac, getApplicationContext());
|
||||
// Gget the AP gateway ip address
|
||||
// https://stackoverflow.com/questions/9035784/how-to-know-ip-address-of-the-router-from-code-in-android
|
||||
billingClient.start("192.168.43.1");
|
||||
final WifiManager manager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
|
||||
final DhcpInfo dhcp = manager.getDhcpInfo();
|
||||
byte[] myIPAddress = BigInteger.valueOf(dhcp.gateway).toByteArray();
|
||||
ArrayUtils.reverse(myIPAddress);
|
||||
InetAddress myInetIP = null;
|
||||
String routerIP = null;
|
||||
try {
|
||||
myInetIP = InetAddress.getByAddress(myIPAddress);
|
||||
routerIP = myInetIP.getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
routerIP = "192.168.43.1";
|
||||
}
|
||||
Log.d(TAG, "DHCP gateway: " + routerIP);
|
||||
billingClient.start(routerIP);
|
||||
// ToDo: handle billingServer EXIT CODES
|
||||
// -> close the roaming etc.
|
||||
}
|
||||
};
|
||||
Thread thread = new Thread(task);
|
||||
threads.add(thread);
|
||||
AsyncTask.execute(thread);
|
||||
thread.start();
|
||||
//AsyncTask.execute(thread);
|
||||
} else {
|
||||
Log.d(TAG, "startBillingClient: blocked");
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,27 +329,45 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void startNegotiationServer(final boolean isClient, String macAddress) {
|
||||
Runnable task = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Negotiator negotiator = new Negotiator(isClient, getWFDMacAddress());
|
||||
Negotiator negotiator = new Negotiator(isClient,
|
||||
getWFDMacAddress(),
|
||||
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()),
|
||||
getBaseContext()
|
||||
);
|
||||
|
||||
String peer_mac_address = null;
|
||||
while (!isRoaming && enabled && peer_mac_address == null) {
|
||||
boolean restartAfterwards = true;
|
||||
int error_count = 0;
|
||||
int max_error_count = 10;
|
||||
Negotiator.NegotiationReturn ret = null;
|
||||
while (!isRoaming && enabled && peer_mac_address == null && restartAfterwards && (error_count < max_error_count)) {
|
||||
Log.d(TAG, String.format("%d/%d errors", error_count, max_error_count));
|
||||
Log.d(TAG, "run: " + enabled);
|
||||
peer_mac_address = negotiator.workAsServer();
|
||||
// ToDo: use other broadcast for this
|
||||
// sendUpdateUIBroadcast();
|
||||
ret = negotiator.workAsServer();
|
||||
peer_mac_address = ret.mac;
|
||||
restartAfterwards = ret.restartAfterwards;
|
||||
if (ret.code != 0) {
|
||||
sendUpdateUIBroadcastWithMessage(getString(ret.code));
|
||||
if (restartAfterwards) {
|
||||
error_count++;
|
||||
}
|
||||
}
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
error_count++;
|
||||
}
|
||||
if (peer_mac_address == null) {
|
||||
deletePersistentGroups();
|
||||
}
|
||||
}
|
||||
if (peer_mac_address != null) {
|
||||
if (peer_mac_address != null && ret != null && ret.code == 0) {
|
||||
// block the discovery mode due to switch to roaming state
|
||||
setRoaming(true);
|
||||
// tell the UI
|
||||
@ -242,15 +375,22 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
String ssid = negFin.getHotspotName();
|
||||
String key = negFin.getHotspotPassword();
|
||||
sendStartRoamingBroadcast(peer_mac_address, ssid, key);
|
||||
} else if (peer_mac_address != null) {
|
||||
PeerStore.getInstance().unselectAll();
|
||||
}
|
||||
negotiatorRunning = false;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
if (!isRoaming()) {
|
||||
if (!isRoaming() && !negotiatorRunning) {
|
||||
negotiatorRunning = true;
|
||||
Thread thread = new Thread(task);
|
||||
threads.add(thread);
|
||||
AsyncTask.execute(thread);
|
||||
//AsyncTask.execute(thread);
|
||||
stopAllTasks();
|
||||
thread.start();
|
||||
//stopDiscovery(null);
|
||||
} else {
|
||||
Log.d(TAG, "startNegServer: BLOCKED due to roaming state");
|
||||
}
|
||||
@ -269,12 +409,24 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
Runnable task = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Negotiator negotiator = new Negotiator(isClient, getWFDMacAddress());
|
||||
Negotiator negotiator = new Negotiator(
|
||||
isClient,
|
||||
getWFDMacAddress(),
|
||||
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()),
|
||||
getBaseContext()
|
||||
);
|
||||
String peer_mac_address = null;
|
||||
while (!isRoaming && enabled && peer_mac_address == null) {
|
||||
boolean restartAfterwards = true;
|
||||
Negotiator.NegotiationReturn negotiationReturn = null;
|
||||
while (!isRoaming && enabled && peer_mac_address == null && restartAfterwards && negotiatorRunning) {
|
||||
Log.d(TAG, "run: " + enabled);
|
||||
System.out.println(" *******+ work as client *******");
|
||||
peer_mac_address = negotiator.workAsClient(address.getHostAddress());
|
||||
negotiationReturn = negotiator.workAsClient(address.getHostAddress());
|
||||
peer_mac_address = negotiationReturn.mac;
|
||||
restartAfterwards = negotiationReturn.restartAfterwards;
|
||||
if (negotiationReturn.code != 0) {
|
||||
sendUpdateUIBroadcastWithMessage(getString(negotiationReturn.code));
|
||||
}
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
@ -284,7 +436,7 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
deletePersistentGroups();
|
||||
}
|
||||
}
|
||||
if (peer_mac_address != null) {
|
||||
if (peer_mac_address != null && negotiationReturn != null && negotiationReturn.code == 0) {
|
||||
// block the discovery mode due to switch to roaming state
|
||||
setRoaming(true);
|
||||
// tell the UI
|
||||
@ -292,15 +444,21 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
String ssid = negFin.getHotspotName();
|
||||
String key = negFin.getHotspotPassword();
|
||||
sendStartRoamingBroadcast(peer_mac_address, ssid, key);
|
||||
} else {
|
||||
Log.d(TAG, "run: could not start roaming");
|
||||
}
|
||||
PeerStore.getInstance().unselectAll();
|
||||
negotiatorRunning = false;
|
||||
}
|
||||
};
|
||||
if (!isRoaming()) {
|
||||
if (!isRoaming() && !negotiatorRunning) {
|
||||
negotiatorRunning = true;
|
||||
Thread thread = new Thread(task);
|
||||
threads.add(thread);
|
||||
AsyncTask.execute(thread);
|
||||
stopAllTasks();
|
||||
thread.start();
|
||||
} else {
|
||||
Log.d(TAG, "startNegotiationClient: BLOCKED due to roaming state");
|
||||
Log.d(TAG, "startNegotiationClient: BLOCKED due to roaming state or negotiator running");
|
||||
}
|
||||
|
||||
|
||||
@ -385,8 +543,10 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
}
|
||||
|
||||
public void startDiscoveryMode(WifiP2pManager.ActionListener action_listener) {
|
||||
mManager.discoverPeers(mChannel, action_listener);
|
||||
discoveryModeActive = true;
|
||||
if (setup) {
|
||||
mManager.discoverPeers(mChannel, action_listener);
|
||||
discoveryModeActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isInRoleHotspot() {
|
||||
@ -410,12 +570,181 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
}
|
||||
|
||||
public void setRoaming(boolean roaming) {
|
||||
if (roaming) {
|
||||
if (!roaming) {
|
||||
stopAllTasks();
|
||||
}
|
||||
isRoaming = roaming;
|
||||
}
|
||||
|
||||
public void freezeWiFiP2P() {
|
||||
|
||||
}
|
||||
|
||||
public void fundChannel(String address) {
|
||||
// get the necessary data
|
||||
NegotiationOffer offer = PeerStore.getInstance().getLatestNegotiationOffer(address);
|
||||
NegotiationOfferAnswer offerAnser = PeerStore.getInstance().getLatestNegotiationOfferAnswer(address);
|
||||
NegotiationFinalization finalization = PeerStore.getInstance().getLatestFinalization(address);
|
||||
BillingOpenChannel openChannel = PeerStore.getInstance().getPeer(address).getBillingOpenChannel();
|
||||
BillingOpenChannelAnswer openChannelAnswer = PeerStore.getInstance().getPeer(address).getBillingOpenChannelAnswer();
|
||||
|
||||
String multisigAddress = finalization.getDepositAddressFlashChannel();
|
||||
|
||||
int timeoutClientSeconds = openChannel.getTimeoutMinutesClient();
|
||||
int timeoutHotspotSeconds = openChannelAnswer.getTimeoutMinutesHotspot() * 60;
|
||||
int timeout = (isInRoleHotspot()) ? timeoutHotspotSeconds : timeoutClientSeconds;
|
||||
|
||||
int clientDeposit = finalization.getDepositClientFlashChannelInIota();
|
||||
int hotspotDeposit = finalization.getDepositServerFlashChannelInIota();
|
||||
int deposit = (isInRoleHotspot()) ? hotspotDeposit : clientDeposit;
|
||||
|
||||
int depositTogether = clientDeposit + hotspotDeposit;
|
||||
|
||||
String seed = Accountant.getInstance().getSeed();
|
||||
|
||||
Log.d(TAG, "fundChannel: Let's fund " + multisigAddress);
|
||||
|
||||
|
||||
Runnable task = () -> {
|
||||
Log.d(TAG, "run: fund multisig address");
|
||||
|
||||
boolean fundDone = false;
|
||||
boolean fundIsThere = false;
|
||||
|
||||
int fundErrorCount = 0;
|
||||
int maxFundErrors = 10;
|
||||
|
||||
SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||
boolean testnet = prefManager.getBoolean("pref_key_switch_testnet",false);
|
||||
|
||||
IotaAPI api;
|
||||
|
||||
if(testnet){
|
||||
//Testnet node:
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol("https")
|
||||
.host("testnet140.tangle.works")
|
||||
.port("443")
|
||||
.build();
|
||||
}
|
||||
else{
|
||||
//Mainnet node:
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol("http")
|
||||
.host("node.iotawallet.info")
|
||||
.port("14265")
|
||||
.build();
|
||||
}
|
||||
|
||||
long start = System.currentTimeMillis() / 1000L;
|
||||
|
||||
while (((System.currentTimeMillis()/1000L) - start < timeout || !fundDone || !fundIsThere) && fundErrorCount < maxFundErrors) {
|
||||
SendTransferResponse sendTransferResponse = null;
|
||||
if (!fundDone) {
|
||||
Log.d(TAG, "fundChannel: DEPOSIT::" + Integer.toString(deposit));
|
||||
try {
|
||||
List<Transfer> transfers = new ArrayList<>();
|
||||
transfers.add(new Transfer(multisigAddress, deposit, "", ""));
|
||||
|
||||
if(testnet) {
|
||||
Log.d(TAG, "fundChannel: fund on testnet");
|
||||
sendTransferResponse = api.sendTransfer(seed, 2, 4, 9, transfers, null, null, false);
|
||||
}
|
||||
else{
|
||||
Log.d(TAG, "fundChannel: fund on mainnet");
|
||||
sendTransferResponse = api.sendTransfer(seed, 2, 4, 18, transfers, null, null, false);
|
||||
}
|
||||
} catch (ArgumentException | IllegalAccessError | IllegalStateException e) {
|
||||
String transferResult = "";
|
||||
if (e instanceof ArgumentException) {
|
||||
if (e.getMessage().contains("Sending to a used address.") || e.getMessage().contains("Private key reuse detect!") || e.getMessage().contains("Send to inputs!")) {
|
||||
transferResult = "Sending to a used address/Private key reuse detect. Error Occurred.";
|
||||
}
|
||||
else if(e.getMessage().contains("Failed to connect to node")){
|
||||
transferResult = "Failed to connect to node";
|
||||
}
|
||||
else{
|
||||
transferResult = "Network Error: Attaching new address failed or Transaction failed";
|
||||
}
|
||||
}
|
||||
if (e instanceof IllegalAccessError) {
|
||||
transferResult = "Local POW needs to be enabled";
|
||||
}
|
||||
fundErrorCount++;
|
||||
Log.d(TAG, "fundChannel: " + transferResult);
|
||||
}
|
||||
|
||||
if(sendTransferResponse != null){
|
||||
Boolean[] transferSuccess = sendTransferResponse.getSuccessfully();
|
||||
|
||||
Boolean success = true;
|
||||
for (Boolean status : transferSuccess) {
|
||||
if(status.equals(false)){
|
||||
success = false;
|
||||
fundErrorCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(success){
|
||||
Log.d(TAG, "fundChannel: successfully transferred my part");
|
||||
fundDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
} else if (fundDone && !fundIsThere) {
|
||||
// now check the balance until we get it
|
||||
// check the funding
|
||||
Log.d(TAG, "fundChannel: checking the balance of the root...");
|
||||
List<String> addresses = new ArrayList<String>();
|
||||
addresses.add(multisigAddress);
|
||||
GetBalancesResponse response = null;
|
||||
try {
|
||||
response = api.getBalances(100, addresses);
|
||||
} catch (ArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (response != null) {
|
||||
if (response.getBalances().length > 0) {
|
||||
long balance = Integer.parseInt(response.getBalances()[0]);
|
||||
Log.d(TAG, "fundChannel: Found balance " + response.getBalances()[0]);
|
||||
if (balance > depositTogether) {
|
||||
Log.d(TAG, "fundChannel: balance is enough on both sides");
|
||||
fundIsThere = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (fundErrorCount < maxFundErrors) {
|
||||
Log.d(TAG, "fundChannel: channel funded");
|
||||
sendUpdateRoamingBroadcastWithMessage("Channel funded");
|
||||
} else {
|
||||
Log.d(TAG, "fundChannel: too many fund errors");
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
Log.d(TAG, "startFunding");
|
||||
Thread thread = new Thread(task);
|
||||
threads.add(thread);
|
||||
thread.start();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class used for the client Binder. Because we know this service always
|
||||
@ -454,7 +783,9 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
}
|
||||
|
||||
public void getPeerList(WifiP2pManager.ActionListener action_listener) {
|
||||
mManager.discoverPeers(mChannel, action_listener);
|
||||
if (setup) {
|
||||
mManager.discoverPeers(mChannel, action_listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopDiscovery(WifiP2pManager.ActionListener action_listener) {
|
||||
@ -507,6 +838,13 @@ public class WiFiDirectBroadcastService extends Service {
|
||||
this.sendBroadcast(local);
|
||||
}
|
||||
|
||||
private void sendUpdateRoamingBroadcastWithMessage(String message){
|
||||
Intent local = new Intent();
|
||||
local.putExtra("message", message);
|
||||
local.setAction("com.flashwifi.wifip2p.update_roaming");
|
||||
this.sendBroadcast(local);
|
||||
}
|
||||
|
||||
public void connect(String address, WifiP2pManager.ActionListener actionListener) {
|
||||
WifiP2pDevice device;
|
||||
WifiP2pConfig config = new WifiP2pConfig();
|
||||
|
||||
@ -4,6 +4,10 @@ import android.net.wifi.p2p.WifiP2pDevice;
|
||||
import android.net.wifi.p2p.WifiP2pInfo;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.flashwifi.wifip2p.protocol.BillingCloseChannel;
|
||||
import com.flashwifi.wifip2p.protocol.BillingCloseChannelAnswer;
|
||||
import com.flashwifi.wifip2p.protocol.BillingOpenChannel;
|
||||
import com.flashwifi.wifip2p.protocol.BillingOpenChannelAnswer;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationFinalization;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOffer;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOfferAnswer;
|
||||
@ -17,6 +21,7 @@ public class PeerInformation {
|
||||
private WifiP2pDevice wifiP2pDevice;
|
||||
private Date lastUpdate;
|
||||
private boolean selected;
|
||||
private String errorMessage = "info";
|
||||
|
||||
// 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 +31,11 @@ public class PeerInformation {
|
||||
private NegotiationOfferAnswer latestOfferAnswer;
|
||||
private NegotiationFinalization latestFinalization;
|
||||
|
||||
private BillingOpenChannel billingOpenChannel;
|
||||
private BillingOpenChannelAnswer billingOpenChannelAnswer;
|
||||
private BillingCloseChannel billingCloseChannel;
|
||||
private BillingCloseChannelAnswer billingCloseChannelAnswer;
|
||||
|
||||
public PeerInformation() {
|
||||
selected = false;
|
||||
age = 0;
|
||||
@ -55,6 +65,8 @@ public class PeerInformation {
|
||||
return latestNegotiationOffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setLatestOfferAnswer(NegotiationOfferAnswer latestOfferAnswer) {
|
||||
this.latestOfferAnswer = latestOfferAnswer;
|
||||
}
|
||||
@ -86,4 +98,44 @@ public class PeerInformation {
|
||||
public void setSelected(boolean selected) {
|
||||
this.selected = selected;
|
||||
}
|
||||
|
||||
public void setErrorMessage(String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public BillingOpenChannel getBillingOpenChannel() {
|
||||
return billingOpenChannel;
|
||||
}
|
||||
|
||||
public void setBillingOpenChannel(BillingOpenChannel billingOpenChannel) {
|
||||
this.billingOpenChannel = billingOpenChannel;
|
||||
}
|
||||
|
||||
public BillingOpenChannelAnswer getBillingOpenChannelAnswer() {
|
||||
return billingOpenChannelAnswer;
|
||||
}
|
||||
|
||||
public void setBillingOpenChannelAnswer(BillingOpenChannelAnswer billingOpenChannelAnswer) {
|
||||
this.billingOpenChannelAnswer = billingOpenChannelAnswer;
|
||||
}
|
||||
|
||||
public BillingCloseChannel getBillingCloseChannel() {
|
||||
return billingCloseChannel;
|
||||
}
|
||||
|
||||
public void setBillingCloseChannel(BillingCloseChannel billingCloseChannel) {
|
||||
this.billingCloseChannel = billingCloseChannel;
|
||||
}
|
||||
|
||||
public BillingCloseChannelAnswer getBillingCloseChannelAnswer() {
|
||||
return billingCloseChannelAnswer;
|
||||
}
|
||||
|
||||
public void setBillingCloseChannelAnswer(BillingCloseChannelAnswer billingCloseChannelAnswer) {
|
||||
this.billingCloseChannelAnswer = billingCloseChannelAnswer;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TableRow;
|
||||
import android.widget.TextView;
|
||||
|
||||
@ -41,8 +42,7 @@ 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);
|
||||
TextView tt4 = (TextView) v.findViewById(R.id.iotaPrice);
|
||||
|
||||
|
||||
WifiP2pDevice device = p.getWifiP2pDevice();
|
||||
@ -58,22 +58,22 @@ public class PeerListAdapter extends ArrayAdapter<PeerInformation> {
|
||||
|
||||
NegotiationOffer offer = p.getLatestNegotiationOffer();
|
||||
if (offer != null) {
|
||||
tt5.setText(Integer.toString(offer.getIotaPerMegabyte()));
|
||||
tt4.setText(Integer.toString(offer.getIotaPerMegabyte()) + "i");
|
||||
}
|
||||
|
||||
if (p.getIpAddress() != null) {
|
||||
tt4.setText(p.getIpAddress());
|
||||
if (!p.isSelected()) {
|
||||
ProgressBar progress_bar = (ProgressBar) v.findViewById(R.id.progressConnection);
|
||||
progress_bar.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
if (tt3 != null)
|
||||
tt3.setText(String.format("%s", Integer.toString(p.getAge())));
|
||||
if (tt3 != null) {
|
||||
tt3.setText(p.getErrorMessage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,5 +1,9 @@
|
||||
package com.flashwifi.wifip2p.datastore;
|
||||
|
||||
import com.flashwifi.wifip2p.protocol.BillingCloseChannel;
|
||||
import com.flashwifi.wifip2p.protocol.BillingCloseChannelAnswer;
|
||||
import com.flashwifi.wifip2p.protocol.BillingOpenChannel;
|
||||
import com.flashwifi.wifip2p.protocol.BillingOpenChannelAnswer;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationFinalization;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOffer;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOfferAnswer;
|
||||
@ -87,6 +91,20 @@ public class PeerStore {
|
||||
getOrCreatePeer(macAddress.toLowerCase()).setLatestOffer(offer);
|
||||
}
|
||||
|
||||
public void setErrorMessage(String macAddress, String msg) {
|
||||
getOrCreatePeer(macAddress.toLowerCase()).setErrorMessage(msg);
|
||||
}
|
||||
|
||||
public void setSelected(String macAddress, boolean selected) {
|
||||
getOrCreatePeer(macAddress.toLowerCase()).setSelected(selected);
|
||||
}
|
||||
|
||||
public void unselectAll() {
|
||||
for (PeerInformation p: peers.values()) {
|
||||
p.setSelected(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void setLatestOfferAnswer(String macAddress, NegotiationOfferAnswer answer) {
|
||||
getOrCreatePeer(macAddress.toLowerCase()).setLatestOfferAnswer(answer);
|
||||
}
|
||||
@ -102,7 +120,46 @@ public class PeerStore {
|
||||
return null;
|
||||
}
|
||||
|
||||
public NegotiationOffer getLatestNegotiationOffer(String macAddress) {
|
||||
if (peers.containsKey(macAddress.toLowerCase())) {
|
||||
return peers.get(macAddress.toLowerCase()).getLatestNegotiationOffer();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public NegotiationOfferAnswer getLatestNegotiationOfferAnswer(String macAddress) {
|
||||
if (peers.containsKey(macAddress.toLowerCase())) {
|
||||
return peers.get(macAddress.toLowerCase()).getLatestOfferAnswer();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setIPAddress(String macAddress, InetAddress IPAddress) {
|
||||
getOrCreatePeer(macAddress.toLowerCase()).setIPAddress(IPAddress.getHostAddress());
|
||||
}
|
||||
|
||||
public void setLatestBillingOpenChannel(String macAddress, BillingOpenChannel o) {
|
||||
getOrCreatePeer(macAddress.toLowerCase()).setBillingOpenChannel(o);
|
||||
}
|
||||
|
||||
public void setLatestBillingOpenChannelAnswer(String macAddress, BillingOpenChannelAnswer o) {
|
||||
getOrCreatePeer(macAddress.toLowerCase()).setBillingOpenChannelAnswer(o);
|
||||
}
|
||||
|
||||
public void setLatestBillingCloseChannel(String macAddress, BillingCloseChannel o) {
|
||||
getOrCreatePeer(macAddress.toLowerCase()).setBillingCloseChannel(o);
|
||||
}
|
||||
|
||||
public void setLatestBillingCloseChannelAnswer(String macAddress, BillingCloseChannelAnswer o) {
|
||||
getOrCreatePeer(macAddress.toLowerCase()).setBillingCloseChannelAnswer(o);
|
||||
}
|
||||
|
||||
public PeerInformation getPeer(String address) {
|
||||
address = address.toLowerCase();
|
||||
if (peers.containsKey(address)) {
|
||||
return peers.get(address);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
package com.flashwifi.wifip2p.iotaAPI.Requests.Model;
|
||||
|
||||
import com.google.api.client.json.GenericJson;
|
||||
import com.google.api.client.util.Key;
|
||||
|
||||
public class TokenGenJSONResponse extends GenericJson {
|
||||
|
||||
@Key("seed")
|
||||
private String seed;
|
||||
@Key("address")
|
||||
private String address;
|
||||
@Key("amount")
|
||||
private Integer amount;
|
||||
|
||||
private String success;
|
||||
|
||||
public Integer getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Integer amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
public void setSeed(String seed) {
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
public String getSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(String success) {
|
||||
this.success = success;
|
||||
}
|
||||
}
|
||||
@ -1,199 +0,0 @@
|
||||
package com.flashwifi.wifip2p.iotaAPI.Requests;
|
||||
|
||||
/**
|
||||
* Created by Toby on 1/6/2018.
|
||||
*/
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
|
||||
import com.flashwifi.wifip2p.AddressBalanceTransfer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jota.IotaAPI;
|
||||
import jota.dto.response.GetBalancesResponse;
|
||||
import jota.dto.response.GetNewAddressResponse;
|
||||
import jota.error.ArgumentException;
|
||||
import jota.model.Transaction;
|
||||
|
||||
public class WalletAddressAndBalanceChecker extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private static final int BALANCE_RETRIEVE_TASK_COMPLETE = 1;
|
||||
|
||||
private static final int FUND_WALLET = 0;
|
||||
private static final int WITHDRAW_WALLET = 1;
|
||||
|
||||
private static IotaAPI api;
|
||||
private static Context context;
|
||||
private String prefFile;
|
||||
private String seed;
|
||||
private Handler mHandler;
|
||||
private int type;
|
||||
private Boolean updateMessage;
|
||||
|
||||
//GetNodeInfoResponse response = api.getNodeInfo();
|
||||
|
||||
public WalletAddressAndBalanceChecker(Context inActivity, String inPrefFile, String inSeed, Handler inMHandler, int inType, Boolean inUpdateMessage) {
|
||||
context = inActivity;
|
||||
prefFile = inPrefFile;
|
||||
seed = inSeed;
|
||||
mHandler = inMHandler;
|
||||
type = inType;
|
||||
updateMessage = inUpdateMessage;
|
||||
|
||||
//Mainnet node:
|
||||
/*
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol("http")
|
||||
.host("node.iotawallet.info")
|
||||
.port("14265")
|
||||
.build();
|
||||
*/
|
||||
|
||||
//Testnet node:
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol("https")
|
||||
.host("testnet140.tangle.works")
|
||||
.port("443")
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
if(context != null){
|
||||
List<String> addressList = getAddress(seed);
|
||||
|
||||
if(addressList != null && addressList.get(0) == "Unable to resolve host"){
|
||||
AddressBalanceTransfer addressBalanceTransfer = new AddressBalanceTransfer(null,null,"hostError");
|
||||
Message completeMessage = mHandler.obtainMessage(BALANCE_RETRIEVE_TASK_COMPLETE, addressBalanceTransfer);
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
else if(addressList != null){
|
||||
|
||||
String depositAddress = addressList.get(addressList.size()-1);
|
||||
String balance = getBalance(addressList);
|
||||
|
||||
if(balance != null){
|
||||
if(type == WITHDRAW_WALLET && updateMessage == false){
|
||||
AddressBalanceTransfer addressBalanceTransfer = new AddressBalanceTransfer(depositAddress,balance,"noErrorNoUpdateMessage");
|
||||
Message completeMessage = mHandler.obtainMessage(BALANCE_RETRIEVE_TASK_COMPLETE,addressBalanceTransfer);
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
else{
|
||||
AddressBalanceTransfer addressBalanceTransfer = new AddressBalanceTransfer(depositAddress,balance,"noError");
|
||||
Message completeMessage = mHandler.obtainMessage(BALANCE_RETRIEVE_TASK_COMPLETE,addressBalanceTransfer);
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
}
|
||||
else{
|
||||
//Balance Retrieval Error
|
||||
AddressBalanceTransfer addressBalanceTransfer = new AddressBalanceTransfer(null,null,"balanceError");
|
||||
Message completeMessage = mHandler.obtainMessage(BALANCE_RETRIEVE_TASK_COMPLETE, addressBalanceTransfer);
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
}
|
||||
else{
|
||||
//Address Retrieval Error
|
||||
AddressBalanceTransfer addressBalanceTransfer = new AddressBalanceTransfer(null,null,"addressError");
|
||||
Message completeMessage = mHandler.obtainMessage(BALANCE_RETRIEVE_TASK_COMPLETE, addressBalanceTransfer);
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getBalance(List<String> inAddresses){
|
||||
String[] balanceArray;
|
||||
try {
|
||||
GetBalancesResponse balanceResultResponse = api.getBalances(100, inAddresses);
|
||||
balanceArray = balanceResultResponse.getBalances();
|
||||
} catch (ArgumentException | IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
if(balanceArray.length>1){
|
||||
return balanceArray[balanceArray.length-2];
|
||||
}
|
||||
else{
|
||||
return balanceArray[balanceArray.length-1];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<String> getAddress(String seed) {
|
||||
|
||||
Boolean foundAddress = false;
|
||||
List<String> addressList = new ArrayList<>();
|
||||
int keyIndex = getKeyIndex();
|
||||
|
||||
while(foundAddress == false){
|
||||
|
||||
GetNewAddressResponse addressResponse = null;
|
||||
try {
|
||||
addressResponse = api.getNewAddress(seed, 2, keyIndex, false, 1, false);
|
||||
} catch (ArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if(addressResponse != null) {
|
||||
addressList.add(addressResponse.getAddresses().get(0));
|
||||
|
||||
String[] addressesCheckArray = new String[1];
|
||||
addressesCheckArray[0] = addressResponse.getAddresses().get(0);
|
||||
|
||||
List<Transaction> transactionsForAddress = null;
|
||||
try {
|
||||
transactionsForAddress = api.findTransactionObjectsByAddresses(addressesCheckArray);
|
||||
} catch (ArgumentException | IllegalStateException | IllegalAccessError e) {
|
||||
e.printStackTrace();
|
||||
if(e.getMessage().contains("Unable to resolve host")){
|
||||
List<String> errorStringList = new ArrayList<>();
|
||||
errorStringList.add("Unable to resolve host");
|
||||
return errorStringList;
|
||||
}
|
||||
}
|
||||
|
||||
if(transactionsForAddress.isEmpty() || (transactionsForAddress.size() == 0 || transactionsForAddress.equals(null))){
|
||||
//Transactions not found, use this address
|
||||
foundAddress = true;
|
||||
}
|
||||
else{
|
||||
//Found transactions, increment for new address
|
||||
keyIndex = keyIndex + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(keyIndex == 0){
|
||||
//Put the initial address to search. No transactions for the seed yet.
|
||||
putKeyIndex(keyIndex);
|
||||
}
|
||||
else{
|
||||
//Put the second last address to search
|
||||
putKeyIndex(keyIndex-1);
|
||||
}
|
||||
return addressList;
|
||||
}
|
||||
|
||||
private int getKeyIndex() {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(prefFile, Context.MODE_PRIVATE);
|
||||
int keyIndex = sharedPref.getInt("keyIndex",0);
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
private void putKeyIndex(int inKeyIndex) {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(
|
||||
prefFile, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putInt("keyIndex", inKeyIndex);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,176 @@
|
||||
package com.flashwifi.wifip2p.iotaAPI.Requests;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.flashwifi.wifip2p.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jota.IotaAPI;
|
||||
import jota.dto.response.GetInclusionStateResponse;
|
||||
import jota.dto.response.GetNewAddressResponse;
|
||||
import jota.error.ArgumentException;
|
||||
import jota.model.Transaction;
|
||||
|
||||
public class WalletAddressChecker {
|
||||
|
||||
private static IotaAPI api;
|
||||
private Context context;
|
||||
private String prefFile;
|
||||
|
||||
boolean containsPendingTransaction = false;
|
||||
boolean keyIndexChanged = false;
|
||||
|
||||
public WalletAddressChecker(Context inContext, String inPrefFile){
|
||||
|
||||
context = inContext;
|
||||
prefFile = inPrefFile;
|
||||
|
||||
SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
Boolean testnet = prefManager.getBoolean("pref_key_switch_testnet",false);
|
||||
Boolean testnetPrivate = prefManager.getBoolean("pref_key_switch_testnet_private",false);
|
||||
|
||||
if(testnet){
|
||||
//Testnet node:
|
||||
if(testnetPrivate){
|
||||
//Private test node
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol(context.getResources().getString(R.string.protocolPrivateTestnetNode))
|
||||
.host(context.getResources().getString(R.string.hostPrivateTestnetNode))
|
||||
.port(context.getResources().getString(R.string.portPrivateTestnetNode))
|
||||
.build();
|
||||
}
|
||||
else{
|
||||
//Public test node
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol(context.getResources().getString(R.string.protocolPublicTestnetNode))
|
||||
.host(context.getResources().getString(R.string.hostPublicTestnetNode))
|
||||
.port(context.getResources().getString(R.string.portPublicTestnetNode))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
else{
|
||||
//Mainnet node:
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol(context.getResources().getString(R.string.protocolDefaultMainnetNode))
|
||||
.host(context.getResources().getString(R.string.hostDefaultMainnetNode))
|
||||
.port(context.getResources().getString(R.string.portDefaultMainnetNode))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getAddress(String seed) {
|
||||
|
||||
Boolean foundAddress = false;
|
||||
List<String> addressList = new ArrayList<>();
|
||||
int keyIndex = getKeyIndex();
|
||||
ArrayList<String> hashStringList = new ArrayList<>();
|
||||
|
||||
while(foundAddress == false){
|
||||
|
||||
GetNewAddressResponse addressResponse = null;
|
||||
try {
|
||||
SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String security = prefManager.getString("pref_key_security","2");
|
||||
int securityInt = Integer.parseInt(security);
|
||||
addressResponse = api.getNewAddress(seed, securityInt, keyIndex, true, 1, false);
|
||||
} catch (ArgumentException e) {
|
||||
e.printStackTrace();
|
||||
return addressList;
|
||||
}
|
||||
|
||||
if(addressResponse != null) {
|
||||
addressList.add(addressResponse.getAddresses().get(0));
|
||||
|
||||
String[] addressesCheckArray = new String[1];
|
||||
addressesCheckArray[0] = addressResponse.getAddresses().get(0);
|
||||
|
||||
List<Transaction> transactionsForAddress = null;
|
||||
try {
|
||||
transactionsForAddress = api.findTransactionObjectsByAddresses(addressesCheckArray);
|
||||
} catch (ArgumentException | IllegalStateException | IllegalAccessError e) {
|
||||
e.printStackTrace();
|
||||
if(e.getMessage().contains("Unable to resolve host")){
|
||||
List<String> errorStringList = new ArrayList<>();
|
||||
errorStringList.add("Unable to resolve host");
|
||||
return errorStringList;
|
||||
}
|
||||
}
|
||||
|
||||
if(transactionsForAddress == null || transactionsForAddress.isEmpty() || (transactionsForAddress.size() == 0)){
|
||||
//Transactions not found, use this address
|
||||
foundAddress = true;
|
||||
}
|
||||
else{
|
||||
//Found transactions, increment for new address
|
||||
|
||||
String curHash = transactionsForAddress.get(0).getHash();
|
||||
hashStringList.add(curHash);
|
||||
keyIndex = keyIndex + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
String[] hashStringArray = new String[hashStringList.size()];
|
||||
int hashIndex = 0;
|
||||
//Convert hash String List to String Array
|
||||
for (String curHash : hashStringList) {
|
||||
hashStringArray[hashIndex] = curHash;
|
||||
hashIndex = hashIndex + 1;
|
||||
}
|
||||
|
||||
//Check whether pending transactions exist
|
||||
containsPendingTransaction = false;
|
||||
keyIndexChanged = false;
|
||||
GetInclusionStateResponse inclusionResponse;
|
||||
try {
|
||||
inclusionResponse = api.getLatestInclusion(hashStringArray);
|
||||
} catch (ArgumentException | IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
return addressList;
|
||||
}
|
||||
|
||||
boolean[] states = inclusionResponse.getStates();
|
||||
|
||||
for (boolean state : states) {
|
||||
if(!state){
|
||||
containsPendingTransaction = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!containsPendingTransaction){
|
||||
//all confirmed transactions, ok to change keyIndex
|
||||
if(keyIndex != getKeyIndex()){
|
||||
keyIndexChanged = true;
|
||||
putKeyIndex(keyIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return addressList;
|
||||
}
|
||||
|
||||
private int getKeyIndex() {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(prefFile, Context.MODE_PRIVATE);
|
||||
int keyIndex = sharedPref.getInt("keyIndex",0);
|
||||
return keyIndex;
|
||||
}
|
||||
|
||||
private void putKeyIndex(int inKeyIndex) {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(
|
||||
prefFile, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putInt("keyIndex", inKeyIndex);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public boolean getContainsPendingTransaction() {
|
||||
return containsPendingTransaction;
|
||||
}
|
||||
|
||||
public boolean getkeyIndexChanged() {
|
||||
return keyIndexChanged;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,217 @@
|
||||
package com.flashwifi.wifip2p.iotaAPI.Requests;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.flashwifi.wifip2p.AddressBalanceTransfer;
|
||||
import com.flashwifi.wifip2p.R;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import jota.IotaAPI;
|
||||
import jota.dto.response.GetBalancesAndFormatResponse;
|
||||
import jota.dto.response.GetBalancesResponse;
|
||||
import jota.error.ArgumentException;
|
||||
import jota.utils.StopWatch;
|
||||
|
||||
public class WalletBalanceChecker extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private static final int BALANCE_RETRIEVE_TASK_COMPLETE = 1;
|
||||
|
||||
private static final int FUND_WALLET = 0;
|
||||
private static final int WITHDRAW_WALLET = 1;
|
||||
private static final int PREF_UPDATE = 2;
|
||||
|
||||
private static IotaAPI api;
|
||||
private static Context context;
|
||||
private String prefFile;
|
||||
private String seed;
|
||||
private Handler mHandler;
|
||||
private int type;
|
||||
private Boolean updateMessage;
|
||||
|
||||
public WalletBalanceChecker(Context inActivity, String inPrefFile, String inSeed, Handler inMHandler, int inType, Boolean inUpdateMessage) {
|
||||
context = inActivity;
|
||||
prefFile = inPrefFile;
|
||||
seed = inSeed;
|
||||
mHandler = inMHandler;
|
||||
type = inType;
|
||||
updateMessage = inUpdateMessage;
|
||||
|
||||
SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
Boolean testnet = prefManager.getBoolean("pref_key_switch_testnet",false);
|
||||
Boolean testnetPrivate = prefManager.getBoolean("pref_key_switch_testnet_private",false);
|
||||
|
||||
if(testnet){
|
||||
//Testnet node:
|
||||
if(testnetPrivate){
|
||||
//Private test node
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol(context.getResources().getString(R.string.protocolPrivateTestnetNode))
|
||||
.host(context.getResources().getString(R.string.hostPrivateTestnetNode))
|
||||
.port(context.getResources().getString(R.string.portPrivateTestnetNode))
|
||||
.build();
|
||||
}
|
||||
else{
|
||||
//Public test node
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol(context.getResources().getString(R.string.protocolPublicTestnetNode))
|
||||
.host(context.getResources().getString(R.string.hostPublicTestnetNode))
|
||||
.port(context.getResources().getString(R.string.portPublicTestnetNode))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
else{
|
||||
//Mainnet node:
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol(context.getResources().getString(R.string.protocolDefaultMainnetNode))
|
||||
.host(context.getResources().getString(R.string.hostDefaultMainnetNode))
|
||||
.port(context.getResources().getString(R.string.portDefaultMainnetNode))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
|
||||
if(context != null){
|
||||
|
||||
WalletAddressChecker addressChecker = new WalletAddressChecker(context,prefFile);
|
||||
List<String> addressList = addressChecker.getAddress(seed);
|
||||
boolean containsPendingTransactions = addressChecker.getContainsPendingTransaction();
|
||||
boolean keyIndexChanged = addressChecker.getkeyIndexChanged();
|
||||
|
||||
if(addressList != null && addressList.get(0).equals("Unable to resolve host")){
|
||||
AddressBalanceTransfer addressBalanceTransfer = new AddressBalanceTransfer(null,null,"hostError");
|
||||
Message completeMessage = mHandler.obtainMessage(BALANCE_RETRIEVE_TASK_COMPLETE, addressBalanceTransfer);
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
else if(addressList != null){
|
||||
|
||||
String depositAddress = addressList.get(addressList.size()-1);
|
||||
String balance = getBalance(addressList, containsPendingTransactions, keyIndexChanged);
|
||||
|
||||
if(balance != null){
|
||||
if(type == WITHDRAW_WALLET && updateMessage == false){
|
||||
AddressBalanceTransfer addressBalanceTransfer = new AddressBalanceTransfer(depositAddress,balance,"noErrorNoUpdateMessage");
|
||||
Message completeMessage = mHandler.obtainMessage(BALANCE_RETRIEVE_TASK_COMPLETE,addressBalanceTransfer);
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
else{
|
||||
AddressBalanceTransfer addressBalanceTransfer = new AddressBalanceTransfer(depositAddress,balance,"noError");
|
||||
Message completeMessage = mHandler.obtainMessage(BALANCE_RETRIEVE_TASK_COMPLETE,addressBalanceTransfer);
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
}
|
||||
else{
|
||||
//Balance Retrieval Error
|
||||
AddressBalanceTransfer addressBalanceTransfer = new AddressBalanceTransfer(null,null,"balanceError");
|
||||
Message completeMessage = mHandler.obtainMessage(BALANCE_RETRIEVE_TASK_COMPLETE, addressBalanceTransfer);
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
}
|
||||
else{
|
||||
//Address Retrieval Error
|
||||
AddressBalanceTransfer addressBalanceTransfer = new AddressBalanceTransfer(null,null,"addressError");
|
||||
Message completeMessage = mHandler.obtainMessage(BALANCE_RETRIEVE_TASK_COMPLETE, addressBalanceTransfer);
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getBalance(List<String> inAddresses, boolean containsPendingTransactions, boolean keyIndexChanged){
|
||||
|
||||
String updatedBalanceString;
|
||||
try {
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
|
||||
SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String security = prefManager.getString("pref_key_security","2");
|
||||
int securityInt = Integer.parseInt(security);
|
||||
|
||||
GetBalancesAndFormatResponse balanceResponse = api.getBalanceAndFormat(inAddresses, 0, 0, stopWatch, securityInt);
|
||||
long total = balanceResponse.getTotalBalance();
|
||||
long storedBaseBalance = Long.parseLong(getBaseSharedPrefKeyBalance());
|
||||
long updatedBaseBalance = storedBaseBalance + total;
|
||||
updatedBalanceString = Long.toString(updatedBaseBalance);
|
||||
|
||||
//Pending Transaction, no new confirmed transactions
|
||||
if(containsPendingTransactions && !keyIndexChanged){
|
||||
//No action required
|
||||
}
|
||||
//Pending Transaction, new confirmed transactions
|
||||
else if(containsPendingTransactions && keyIndexChanged){
|
||||
putSharedPrefBalance(updatedBalanceString);
|
||||
}
|
||||
//No Pending Transactions, no new confirmed transactions
|
||||
else if(!containsPendingTransactions && !keyIndexChanged){
|
||||
//No action required
|
||||
}
|
||||
//No Pending Transactions, new confirmed transactions
|
||||
else if(!containsPendingTransactions && keyIndexChanged){
|
||||
putBaseSharedPrefBalance(updatedBalanceString);
|
||||
updatedBalanceString = Long.toString(updatedBaseBalance);
|
||||
putSharedPrefBalance(updatedBalanceString);
|
||||
}
|
||||
} catch (ArgumentException | IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
return getSharedPrefKeyBalance()+"i (cached: "+getSharedPrefKeyBalanceDateUpdate()+")";
|
||||
}
|
||||
String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
|
||||
putSharedPrefBalanceDateUpdate(currentDateTimeString);
|
||||
return updatedBalanceString+"i";
|
||||
}
|
||||
|
||||
private void putSharedPrefBalanceDateUpdate(String currentDateTimeString) {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(
|
||||
prefFile, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putString("balanceDateUpdate", currentDateTimeString);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
private String getSharedPrefKeyBalanceDateUpdate() {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(prefFile, Context.MODE_PRIVATE);
|
||||
String defaultValue = "0";
|
||||
String storedBalance = sharedPref.getString("balanceDateUpdate",defaultValue);
|
||||
return storedBalance;
|
||||
}
|
||||
|
||||
private String getSharedPrefKeyBalance() {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(prefFile, Context.MODE_PRIVATE);
|
||||
String defaultValue = "0";
|
||||
String storedBalance = sharedPref.getString("balance",defaultValue);
|
||||
return storedBalance;
|
||||
}
|
||||
|
||||
private void putSharedPrefBalance(String inBalance) {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(
|
||||
prefFile, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putString("balance", inBalance);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
private String getBaseSharedPrefKeyBalance() {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(prefFile, Context.MODE_PRIVATE);
|
||||
String defaultValue = "0";
|
||||
String storedBalance = sharedPref.getString("baseBalance",defaultValue);
|
||||
return storedBalance;
|
||||
}
|
||||
|
||||
private void putBaseSharedPrefBalance(String inBalance) {
|
||||
SharedPreferences sharedPref = context.getSharedPreferences(
|
||||
prefFile, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putString("baseBalance", inBalance);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,171 @@
|
||||
package com.flashwifi.wifip2p.iotaAPI.Requests;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.flashwifi.wifip2p.AddressBalanceTransfer;
|
||||
import com.flashwifi.wifip2p.R;
|
||||
import com.flashwifi.wifip2p.iotaAPI.Requests.Model.TokenGenJSONResponse;
|
||||
import com.google.api.client.http.GenericUrl;
|
||||
import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler;
|
||||
import com.google.api.client.http.HttpRequest;
|
||||
import com.google.api.client.http.HttpRequestFactory;
|
||||
import com.google.api.client.http.HttpTransport;
|
||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||
import com.google.api.client.json.JsonFactory;
|
||||
import com.google.api.client.json.JsonObjectParser;
|
||||
import com.google.api.client.json.jackson2.JacksonFactory;
|
||||
import com.google.api.client.util.ExponentialBackOff;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
public class WalletTestnetTokenGen extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private static final int TOKEN_TESTNET_RETRIEVE_TASK_COMPLETE = 0;
|
||||
private static final int TOKEN_TESTNET_STATUS_UPDATE = 1;
|
||||
private static final int TRANSFER_TASK_COMPLETE = 2;
|
||||
private static String seed;
|
||||
private Handler settingsFragmentHandler;
|
||||
private Handler testnetTokenGenHandler;
|
||||
private String prefFile;
|
||||
static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
|
||||
static JsonFactory JSON_FACTORY = new JacksonFactory();
|
||||
private static Context context;
|
||||
|
||||
public WalletTestnetTokenGen(Handler inMHandler, Context inContext, String inPrefFile, String inSeed){
|
||||
settingsFragmentHandler = inMHandler;
|
||||
context = inContext;
|
||||
prefFile = inPrefFile;
|
||||
seed = inSeed;
|
||||
|
||||
//Handle post-asynctask activities of updating UI
|
||||
testnetTokenGenHandler = new Handler(Looper.getMainLooper()) {
|
||||
@Override
|
||||
public void handleMessage(Message inputMessage) {
|
||||
switch (inputMessage.what) {
|
||||
case TRANSFER_TASK_COMPLETE:
|
||||
AddressBalanceTransfer addressBalanceTransfer = (AddressBalanceTransfer) inputMessage.obj;
|
||||
String message = addressBalanceTransfer.getMessage();
|
||||
//Send completion of send funds to settings fragment
|
||||
Message completeMessage = settingsFragmentHandler.obtainMessage(TOKEN_TESTNET_RETRIEVE_TASK_COMPLETE,message);
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public TokenGenJSONResponse genToken() {
|
||||
|
||||
HttpRequestFactory requestFactory
|
||||
= HTTP_TRANSPORT.createRequestFactory(
|
||||
(HttpRequest request) -> {
|
||||
request.setParser(new JsonObjectParser(JSON_FACTORY));
|
||||
});
|
||||
HttpRequest request = null;
|
||||
try {
|
||||
|
||||
SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
Boolean testnetPrivate = prefManager.getBoolean("pref_key_switch_testnet_private",false);
|
||||
|
||||
if(testnetPrivate){
|
||||
request = requestFactory.buildGetRequest(new GenericUrl(context.getResources().getString(R.string.generatorPrivateTestnetNode)));
|
||||
//Set timeout to 10 min
|
||||
request.setConnectTimeout(300000);
|
||||
request.setReadTimeout(600000);
|
||||
}else{
|
||||
request = requestFactory.buildGetRequest(new GenericUrl(context.getResources().getString(R.string.generatorPublicTestnetNode)));
|
||||
//Set timeout to 10 min
|
||||
request.setConnectTimeout(300000);
|
||||
request.setReadTimeout(600000);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//TODO: Set timeout
|
||||
/*
|
||||
ExponentialBackOff backoff = new ExponentialBackOff.Builder()
|
||||
.setInitialIntervalMillis(300000)
|
||||
.setMaxElapsedTimeMillis(900000)
|
||||
.setMaxIntervalMillis(600000)
|
||||
.setMultiplier(1.5)
|
||||
.setRandomizationFactor(0.999)
|
||||
.build();
|
||||
request.setUnsuccessfulResponseHandler(
|
||||
new HttpBackOffUnsuccessfulResponseHandler(backoff));
|
||||
*/
|
||||
|
||||
Type type = new TypeToken<TokenGenJSONResponse>() {}.getType();
|
||||
TokenGenJSONResponse token = new TokenGenJSONResponse();
|
||||
try{
|
||||
token = (TokenGenJSONResponse) request
|
||||
.execute()
|
||||
.parseAs(type);
|
||||
token.setSuccess("Success");
|
||||
}
|
||||
catch (Exception e){
|
||||
if(e.toString().contains("Connection closed by peer")){
|
||||
//Could not reach token gen page
|
||||
token.setSuccess("Connection Error");
|
||||
e.printStackTrace();
|
||||
}
|
||||
else if(e.toString().contains("Unable to resolve host")){
|
||||
//Could not reach token gen page
|
||||
token.setSuccess("Unable to resolve host. Please try again.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
else{
|
||||
//Unknown error
|
||||
token.setSuccess("Unknown Error. Please try again.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
TokenGenJSONResponse token = genToken();
|
||||
if(token.getSuccess().equals("Success")){
|
||||
WalletAddressChecker addressChecker = new WalletAddressChecker(context,prefFile);
|
||||
List<String> destAddressses = addressChecker.getAddress(seed);
|
||||
transferToWallet(destAddressses, token);
|
||||
}
|
||||
else{
|
||||
Message completeMessage = settingsFragmentHandler.obtainMessage(TOKEN_TESTNET_RETRIEVE_TASK_COMPLETE,token.getSuccess());
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void transferToWallet(List<String> destAddressses, TokenGenJSONResponse token) {
|
||||
|
||||
if(destAddressses != null && destAddressses.get(0).equals("Unable to resolve host")){
|
||||
//Host Error
|
||||
Message completeMessage = settingsFragmentHandler.obtainMessage(TOKEN_TESTNET_RETRIEVE_TASK_COMPLETE, "hostError");
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
else if(destAddressses != null){
|
||||
//No Address Retrieval Error
|
||||
Message completeMessage = settingsFragmentHandler.obtainMessage(TOKEN_TESTNET_STATUS_UPDATE, "Sending");
|
||||
completeMessage.sendToTarget();
|
||||
String destAddress = destAddressses.get(destAddressses.size()-1);
|
||||
|
||||
WalletTransferRequest transferRequest = new WalletTransferRequest(destAddress,token.getSeed(),token.getAmount().toString(),"","",context,testnetTokenGenHandler);
|
||||
transferRequest.execute();
|
||||
}
|
||||
else{
|
||||
//Address Retrieval Error
|
||||
Message completeMessage = settingsFragmentHandler.obtainMessage(TOKEN_TESTNET_RETRIEVE_TASK_COMPLETE,"addressError");
|
||||
completeMessage.sendToTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,14 @@
|
||||
package com.flashwifi.wifip2p.iotaAPI.Requests;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.flashwifi.wifip2p.AddressBalanceTransfer;
|
||||
import com.flashwifi.wifip2p.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -21,6 +24,8 @@ public class WalletTransferRequest extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private static IotaAPI api;
|
||||
private static Context context;
|
||||
Boolean testnet;
|
||||
Boolean testnetPrivate;
|
||||
private String appWalletSeed;
|
||||
private String sendAddress;
|
||||
private String sendAmount;
|
||||
@ -39,28 +44,41 @@ public class WalletTransferRequest extends AsyncTask<Void, Void, Void> {
|
||||
context = inContext;
|
||||
mHandler = inMHandler;
|
||||
|
||||
//Mainnet node:
|
||||
/*
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol("http")
|
||||
.host("node.iotawallet.info")
|
||||
.port("14265")
|
||||
.build();
|
||||
*/
|
||||
|
||||
//Testnet node:
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol("https")
|
||||
.host("testnet140.tangle.works")
|
||||
.port("443")
|
||||
.build();
|
||||
SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
testnet = prefManager.getBoolean("pref_key_switch_testnet",false);
|
||||
testnetPrivate = prefManager.getBoolean("pref_key_switch_testnet_private",false);
|
||||
|
||||
if(testnet){
|
||||
//Testnet node:
|
||||
if(testnetPrivate){
|
||||
//Private test node
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol(context.getResources().getString(R.string.protocolPrivateTestnetNode))
|
||||
.host(context.getResources().getString(R.string.hostPrivateTestnetNode))
|
||||
.port(context.getResources().getString(R.string.portPrivateTestnetNode))
|
||||
.build();
|
||||
}
|
||||
else{
|
||||
//Public test node
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol(context.getResources().getString(R.string.protocolPublicTestnetNode))
|
||||
.host(context.getResources().getString(R.string.hostPublicTestnetNode))
|
||||
.port(context.getResources().getString(R.string.portPublicTestnetNode))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
else{
|
||||
//Mainnet node:
|
||||
api = new IotaAPI.Builder()
|
||||
.protocol(context.getResources().getString(R.string.protocolDefaultMainnetNode))
|
||||
.host(context.getResources().getString(R.string.hostDefaultMainnetNode))
|
||||
.port(context.getResources().getString(R.string.portDefaultMainnetNode))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
sendRequest();
|
||||
|
||||
String result = null;
|
||||
|
||||
if(context != null){
|
||||
@ -82,26 +100,36 @@ public class WalletTransferRequest extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
SendTransferResponse sendTransferResponse = null;
|
||||
|
||||
SharedPreferences prefManager = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String security = prefManager.getString("pref_key_security","2");
|
||||
int securityInt = Integer.parseInt(security);
|
||||
|
||||
try {
|
||||
//Mainnet
|
||||
//sendTransferResponse = api.sendTransfer(appWalletSeed, 2, 4, 18, transfers, null, null, false);
|
||||
|
||||
if(testnet) {
|
||||
//Testnet
|
||||
sendTransferResponse = api.sendTransfer(appWalletSeed, 2, 4, 9, transfers, null, null, false);
|
||||
|
||||
if(testnetPrivate){
|
||||
sendTransferResponse = api.sendTransfer(appWalletSeed, securityInt, 4, 3, transfers, null, null, false);
|
||||
}
|
||||
else{
|
||||
sendTransferResponse = api.sendTransfer(appWalletSeed, securityInt, 4, 9, transfers, null, null, false);
|
||||
}
|
||||
}
|
||||
else{
|
||||
//Mainnet
|
||||
sendTransferResponse = api.sendTransfer(appWalletSeed, securityInt, 4, 14, transfers, null, null, false);
|
||||
}
|
||||
} catch (ArgumentException | IllegalAccessError | IllegalStateException e) {
|
||||
if (e instanceof ArgumentException) {
|
||||
if (e.getMessage().contains("Sending to a used address.") || e.getMessage().contains("Private key reuse detect!") || e.getMessage().contains("Send to inputs!")) {
|
||||
transferResult = "Sending to a used address/Private key reuse detect. Error Occurred.";
|
||||
}
|
||||
else if(e.getMessage().contains("Failed to connect to")){
|
||||
transferResult = "Failed to connect to";
|
||||
else if(e.getMessage().contains("Failed to connect to node")){
|
||||
transferResult = "Failed to connect to node";
|
||||
}
|
||||
else{
|
||||
transferResult = "Network Error: Attaching new address failed or Transaction failed";
|
||||
}
|
||||
}
|
||||
|
||||
if (e instanceof IllegalAccessError) {
|
||||
transferResult = "Local POW needs to be enabled";
|
||||
}
|
||||
@ -116,14 +144,12 @@ public class WalletTransferRequest extends AsyncTask<Void, Void, Void> {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(success){
|
||||
transferResult = "Sent";
|
||||
}
|
||||
else{
|
||||
transferResult = "Transfer not successful, check transfer status via Tangle explorer";
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
transferResult = "Transfer error: Send Response not received";
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
package com.flashwifi.wifip2p.negotiation;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.flashwifi.wifip2p.R;
|
||||
import com.flashwifi.wifip2p.datastore.PeerStore;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationFinalization;
|
||||
import com.flashwifi.wifip2p.protocol.NegotiationOffer;
|
||||
@ -11,6 +16,7 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
@ -34,7 +40,12 @@ public class Negotiator {
|
||||
// consumer as in consumer-hotspot
|
||||
private boolean isConsumer;
|
||||
|
||||
String mac = null;
|
||||
String peer_mac_address = null;
|
||||
|
||||
private Gson gson;
|
||||
private SharedPreferences prefs;
|
||||
private Context context;
|
||||
|
||||
public enum ConsumerState {
|
||||
INITIAL,
|
||||
@ -59,18 +70,30 @@ public class Negotiator {
|
||||
ERROR
|
||||
}
|
||||
|
||||
public Negotiator(boolean isConsumer, String ownMacAddress) {
|
||||
private void sendUpdateUIBroadcastWithMessage(String message, String snd_message){
|
||||
Intent local = new Intent();
|
||||
local.putExtra("message", message);
|
||||
local.putExtra("snd_message", snd_message);
|
||||
local.setAction("com.flashwifi.wifip2p.update_ui");
|
||||
context.sendBroadcast(local);
|
||||
}
|
||||
|
||||
public Negotiator(boolean isConsumer, String ownMacAddress, SharedPreferences prefs, Context context) {
|
||||
this.isConsumer = isConsumer;
|
||||
gson = new GsonBuilder().create();
|
||||
this.ownMacAddress = ownMacAddress;
|
||||
this.prefs = prefs;
|
||||
this.context = context;
|
||||
Log.d(TAG, "Negotiator: " + ownMacAddress);
|
||||
}
|
||||
|
||||
public String workAsClient(String serverIPAddress) {
|
||||
public NegotiationReturn workAsClient(String serverIPAddress) {
|
||||
this.isClient = true;
|
||||
|
||||
String success = null;
|
||||
Socket socket = null;
|
||||
NegotiationReturn negReturn;
|
||||
int code = 0;
|
||||
boolean restartAfterwards = false;
|
||||
|
||||
|
||||
try {
|
||||
// create client socket that connects to server
|
||||
@ -87,13 +110,23 @@ public class Negotiator {
|
||||
|
||||
// Whether we want to provide a hotspot or use one
|
||||
if (isConsumer) {
|
||||
success = runConsumerProtocol(serverIPAddress);
|
||||
negReturn = runConsumerProtocol(serverIPAddress);
|
||||
} else {
|
||||
success = runHotspotProtocol(serverIPAddress);
|
||||
negReturn = runHotspotProtocol(serverIPAddress);
|
||||
}
|
||||
|
||||
mac = negReturn.mac;
|
||||
restartAfterwards = negReturn.restartAfterwards;
|
||||
code = negReturn.code;
|
||||
} catch (SocketTimeoutException ste) {
|
||||
Log.d(TAG, "workAsServer: ### Timed out after 1 seconds");
|
||||
mac = null;
|
||||
restartAfterwards = true;
|
||||
code = R.string.err_timeout;
|
||||
Log.d(TAG, "workAsServer: ### Timed out");
|
||||
} catch (IOException e) {
|
||||
mac = null;
|
||||
restartAfterwards = true;
|
||||
code = R.string.err_io_exception;
|
||||
Log.d("", e.getMessage());
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
@ -104,16 +137,19 @@ public class Negotiator {
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
return new NegotiationReturn(code, mac, restartAfterwards);
|
||||
}
|
||||
|
||||
public String workAsServer() {
|
||||
public NegotiationReturn workAsServer() {
|
||||
// this device is the socket server
|
||||
this.isClient = false;
|
||||
|
||||
String peer_mac_address = null;
|
||||
peer_mac_address = null;
|
||||
ServerSocket serverSocket = null;
|
||||
Socket socket = null;
|
||||
int code = 0;
|
||||
NegotiationReturn negReturn;
|
||||
boolean restartAfterwards = false;
|
||||
|
||||
try {
|
||||
// use the port to start
|
||||
@ -131,28 +167,36 @@ public class Negotiator {
|
||||
// WAIT FOR CLIENT
|
||||
String hello = socketWrapper.getLine();
|
||||
|
||||
if (hello == null) {
|
||||
error(0, "no hello received");
|
||||
return null;
|
||||
if (hello == null || hello.contains("java.net.SocketException")) {
|
||||
return error(R.string.no_hello_received, true);
|
||||
}
|
||||
|
||||
// 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 null;
|
||||
return error(R.string.err_pairing_roles_broken, true);
|
||||
}
|
||||
|
||||
// Whether we want to provide a hotspot or use one
|
||||
if (isConsumer) {
|
||||
peer_mac_address = runConsumerProtocol(socketWrapper.getClientAddress().getHostAddress());
|
||||
negReturn = runConsumerProtocol(socketWrapper.getClientAddress().getHostAddress());
|
||||
} else {
|
||||
peer_mac_address = runHotspotProtocol(socketWrapper.getClientAddress().getHostAddress());
|
||||
negReturn = runHotspotProtocol(socketWrapper.getClientAddress().getHostAddress());
|
||||
}
|
||||
peer_mac_address = negReturn.mac;
|
||||
code = negReturn.code;
|
||||
restartAfterwards = negReturn.restartAfterwards;
|
||||
|
||||
} catch (SocketTimeoutException ste) {
|
||||
Log.d(TAG, "workAsServer: ### Timed out after 1 seconds");
|
||||
Log.d(TAG, "workAsServer: ### Timed out");
|
||||
code = R.string.err_timeout;
|
||||
peer_mac_address = null;
|
||||
restartAfterwards = true;
|
||||
} catch (IOException e) {
|
||||
Log.d("", e.getMessage());
|
||||
Log.d(TAG, e.getMessage());
|
||||
code = R.string.err_io_exception;
|
||||
peer_mac_address = null;
|
||||
restartAfterwards = true;
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
try {
|
||||
@ -168,19 +212,17 @@ public class Negotiator {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return peer_mac_address;
|
||||
return new NegotiationReturn(code, peer_mac_address, restartAfterwards);
|
||||
}
|
||||
|
||||
private String runConsumerProtocol(String ipAddress) throws IOException {
|
||||
private NegotiationReturn 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 null;
|
||||
if (offerString == null || offerString.contains("java.net.SocketException")) {
|
||||
return error(R.string.err_no_offer_received, true);
|
||||
}
|
||||
|
||||
// CHECK OFFER
|
||||
@ -190,26 +232,49 @@ public class Negotiator {
|
||||
// Write offer to the PeerStore
|
||||
PeerStore.getInstance().setLatestOffer(otherMac, offer);
|
||||
|
||||
// ToDo: implement accept or deny logic
|
||||
if (!true) {
|
||||
error(3, "Offer not acceptable");
|
||||
return null;
|
||||
// accept or deny logic
|
||||
boolean agree = true;
|
||||
int disagree_reason = 0;
|
||||
int iotaPerMegabyte = Integer.valueOf(prefs.getString("edit_text_buy_price", "-1"));
|
||||
if (iotaPerMegabyte < 0) {
|
||||
return error(R.string.err_buy_price_bad_setting, false);
|
||||
}
|
||||
if (offer.getIotaPerMegabyte() > iotaPerMegabyte) {
|
||||
agree = false;
|
||||
disagree_reason = R.string.err_price_too_high;
|
||||
}
|
||||
|
||||
int hotspot_max_minutes = offer.getMaxMinutes();
|
||||
int hotspot_min_minutes = offer.getMinMinutes();
|
||||
int client_roaming_minutes = Integer.valueOf(prefs.getString("edit_text_client_minutes", "-1"));
|
||||
|
||||
if (client_roaming_minutes < 0) {
|
||||
return error(R.string.err_client_minutes_bad_setting, false);
|
||||
}
|
||||
|
||||
if (client_roaming_minutes < hotspot_min_minutes || client_roaming_minutes > hotspot_max_minutes) {
|
||||
agree = false;
|
||||
disagree_reason = R.string.err_client_minutes_not_acceptable_for_hotspot;
|
||||
}
|
||||
|
||||
// SEND NegotiationAnswer
|
||||
// ToDo: where shall the input come from?
|
||||
NegotiationOfferAnswer answer = new NegotiationOfferAnswer(true, 10, ownMacAddress);
|
||||
NegotiationOfferAnswer answer = new NegotiationOfferAnswer(agree, client_roaming_minutes, ownMacAddress);
|
||||
PeerStore.getInstance().setLatestOfferAnswer(otherMac, answer);
|
||||
String answerString = gson.toJson(answer);
|
||||
socketWrapper.sendLine(answerString);
|
||||
|
||||
if (!agree) {
|
||||
return error(disagree_reason, false);
|
||||
}
|
||||
|
||||
// WAIT FOR PASSWORD and hostname
|
||||
consumer_state = ConsumerState.WAIT_FOR_PASSWORD;
|
||||
String finalizationString = socketWrapper.getLine();
|
||||
|
||||
if (finalizationString == null) {
|
||||
error(4, "No finalization received");
|
||||
return null;
|
||||
if (finalizationString == null || finalizationString.contains("java.net.SocketException")) {
|
||||
return error(R.string.err_no_finalization_received, true);
|
||||
} else if (answerString.equals("BYE")) {
|
||||
return error(R.string.err_peer_quit, false);
|
||||
}
|
||||
|
||||
NegotiationFinalization finalization = gson.fromJson(finalizationString, NegotiationFinalization.class);
|
||||
@ -224,16 +289,27 @@ public class Negotiator {
|
||||
// End
|
||||
socketWrapper.close();
|
||||
|
||||
return otherMac;
|
||||
return new NegotiationReturn(0, otherMac, false);
|
||||
}
|
||||
|
||||
private String runHotspotProtocol(String ipAddress) throws IOException {
|
||||
private NegotiationReturn runHotspotProtocol(String ipAddress) throws IOException {
|
||||
// CHECK_CLIENT_REQUEST
|
||||
hotspot_state = HotspotState.CHECK_CLIENT_REQUEST;
|
||||
|
||||
// send offer
|
||||
int iotaPerMegabyte = (int) (Math.random() * (1000 - 10)) + 10;
|
||||
NegotiationOffer offer = new NegotiationOffer(1, 100, iotaPerMegabyte, ownMacAddress);
|
||||
int iotaPerMegabyte = Integer.valueOf(prefs.getString("edit_text_sell_price", "-1"));
|
||||
if (iotaPerMegabyte < 0) {
|
||||
return error(R.string.err_sell_price_bad_setting, false);
|
||||
}
|
||||
int minMinutes = Integer.valueOf(prefs.getString("edit_text_sell_min_minutes", "-1"));
|
||||
if (minMinutes < 0) {
|
||||
return error(R.string.err_min_minutes_bad_setting, false);
|
||||
}
|
||||
int maxMinutes = Integer.valueOf(prefs.getString("edit_text_sell_max_minutes", "-1"));
|
||||
if (maxMinutes < 0) {
|
||||
return error(R.string.err_max_minutes_bad_setting, false);
|
||||
}
|
||||
NegotiationOffer offer = new NegotiationOffer(minMinutes, maxMinutes, iotaPerMegabyte, ownMacAddress);
|
||||
|
||||
String offerString = gson.toJson(offer);
|
||||
socketWrapper.sendLine(offerString);
|
||||
@ -242,14 +318,16 @@ public class Negotiator {
|
||||
hotspot_state = HotspotState.WAIT_FOR_ANSWER;
|
||||
String answerString = socketWrapper.getLine();
|
||||
|
||||
if (answerString == null) {
|
||||
error(8, "No answer received");
|
||||
return null;
|
||||
if (answerString == null || answerString.contains("java.net.SocketException")) {
|
||||
return error(R.string.err_no_answer_received, true);
|
||||
} else if (answerString.equals("BYE")) {
|
||||
return error(R.string.err_peer_quit, false);
|
||||
}
|
||||
|
||||
// Parse the answer
|
||||
NegotiationOfferAnswer answer = gson.fromJson(answerString, NegotiationOfferAnswer.class);
|
||||
String otherMac = answer.getConsumerMac();
|
||||
peer_mac_address = otherMac;
|
||||
PeerStore.getInstance().setLatestOffer(otherMac, offer);
|
||||
PeerStore.getInstance().setLatestOfferAnswer(otherMac, answer);
|
||||
|
||||
@ -257,8 +335,11 @@ public class Negotiator {
|
||||
hotspot_state = HotspotState.CHECK_ANSWER;
|
||||
|
||||
if (!answer.isAgreeToConditions()) {
|
||||
error(5, "Client does not agree to conditions");
|
||||
return null;
|
||||
return error(R.string.err_client_does_not_agree, false);
|
||||
}
|
||||
|
||||
if (answer.getDuranceInMinutes() > maxMinutes || answer.getDuranceInMinutes() < minMinutes) {
|
||||
return error(R.string.err_client_minutes_out_of_bounds, false);
|
||||
}
|
||||
|
||||
// CHECK_ITP
|
||||
@ -266,7 +347,6 @@ public class Negotiator {
|
||||
// if (!true) {
|
||||
// writeError(0, "");
|
||||
// server_state = NegotiationServerTask.State.ERROR;
|
||||
// // ToDo: Error handling
|
||||
// }
|
||||
|
||||
// GENERATE_PASSWORD and hotspot name
|
||||
@ -274,11 +354,20 @@ public class Negotiator {
|
||||
int min = 100000000;
|
||||
int max = 999999999;
|
||||
String password = Integer.toString(ThreadLocalRandom.current().nextInt(min, max + 1));
|
||||
String hotspotName = "Iotify-"+Integer.toString(ThreadLocalRandom.current().nextInt(100, 10000));;
|
||||
String hotspotName = "Iotify-"+Integer.toString(ThreadLocalRandom.current().nextInt(100, 10000));
|
||||
|
||||
// send password and hotspot name
|
||||
|
||||
// ToDo: get depositAddressFlashChannel from SharedPreferences
|
||||
// ToDo: get the bandwidth of the hotspot
|
||||
// ToDo: create initial flash object
|
||||
double bandwidth = 0.1; // megabyte per second;
|
||||
int max_data_volume_megabytes = (int) (answer.getDuranceInMinutes() * bandwidth);
|
||||
int max_iota_transferred = max_data_volume_megabytes * offer.getIotaPerMegabyte();
|
||||
max_iota_transferred = 10;
|
||||
String rootAddress = "JZWUMRUEYFJOCDDRZCNIIMDZSX9LWMITNMDIAIUJKUV9LVDLSICDABFYTTBZFGEBJOADDN9WZ9IJJJD9DXRJRR9TOW";
|
||||
// send the most important message to the user
|
||||
NegotiationFinalization finalization = new NegotiationFinalization(hotspotName, password,
|
||||
"Address", 0, 0, "");
|
||||
rootAddress, max_iota_transferred, max_iota_transferred, "<flashObj>");
|
||||
PeerStore.getInstance().setLatestFinalization(otherMac, finalization);
|
||||
String finalizationString = gson.toJson(finalization);
|
||||
|
||||
@ -296,20 +385,46 @@ public class Negotiator {
|
||||
|
||||
socketWrapper.close();
|
||||
|
||||
return otherMac;
|
||||
return new NegotiationReturn(0, otherMac, false);
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// HELPER METHODS BELOW
|
||||
// ------------------------
|
||||
|
||||
private void error(int code, String msg) throws IOException {
|
||||
Log.d(TAG, "error: " + msg);
|
||||
private NegotiationReturn error(int err_no, boolean restartAfterwards) throws IOException {
|
||||
String str = context.getString(err_no);
|
||||
Log.d(TAG, "error: " + str);
|
||||
if (isConsumer) {
|
||||
consumer_state = ConsumerState.ERROR;
|
||||
} else {
|
||||
hotspot_state = HotspotState.ERROR;
|
||||
}
|
||||
String macAdd = (restartAfterwards) ? null : this.peer_mac_address;
|
||||
sendUpdateUIBroadcastWithMessage("error", str);
|
||||
if (this.peer_mac_address != null) {
|
||||
PeerStore.getInstance().setErrorMessage(this.peer_mac_address, str);
|
||||
}
|
||||
if (!restartAfterwards) {
|
||||
try {
|
||||
socketWrapper.sendLine("BYE");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
socketWrapper.close();
|
||||
return new NegotiationReturn(err_no, macAdd, restartAfterwards);
|
||||
}
|
||||
|
||||
public class NegotiationReturn {
|
||||
public int code;
|
||||
public String mac;
|
||||
public boolean restartAfterwards;
|
||||
|
||||
public NegotiationReturn(int code, String mac, boolean restartAfterwards) {
|
||||
this.mac = mac;
|
||||
this.code = code;
|
||||
this.restartAfterwards = restartAfterwards;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package com.flashwifi.wifip2p.protocol;
|
||||
|
||||
public class BillingOpenChannel {
|
||||
private int totalMegabytes;
|
||||
private int totalMinutes;
|
||||
private int iotaPerMegabyte;
|
||||
private int timeoutMinutesClient;
|
||||
private String clientRefundAddress;
|
||||
@ -10,8 +11,10 @@ public class BillingOpenChannel {
|
||||
private String[] clientDigests;
|
||||
|
||||
public BillingOpenChannel(int totalMegabytes, int iotaPerMegabyte, String clientRefundAddress,
|
||||
int treeDepth, String[] clientDigests, int timeoutMinutesClient) {
|
||||
int treeDepth, String[] clientDigests, int timeoutMinutesClient,
|
||||
int totalMinutes) {
|
||||
this.totalMegabytes = totalMegabytes;
|
||||
this.totalMinutes = totalMinutes;
|
||||
this.iotaPerMegabyte = iotaPerMegabyte;
|
||||
this.clientRefundAddress = clientRefundAddress;
|
||||
this.treeDepth = treeDepth;
|
||||
@ -42,4 +45,8 @@ public class BillingOpenChannel {
|
||||
public String[] getClientDigests() {
|
||||
return clientDigests;
|
||||
}
|
||||
|
||||
public int getTotalMinutes() {
|
||||
return totalMinutes;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,8 @@ public class NegotiationFinalization {
|
||||
private String hotspotName;
|
||||
private String hotspotPassword;
|
||||
private String depositAddressFlashChannel;
|
||||
private String clientRefundAddress;
|
||||
private String hotspotRefundAddress;
|
||||
private int depositServerFlashChannelInIota;
|
||||
private int depositClientFlashChannelInIota;
|
||||
private String flashObject;
|
||||
@ -27,4 +29,28 @@ public class NegotiationFinalization {
|
||||
public String getHotspotPassword() {
|
||||
return hotspotPassword;
|
||||
}
|
||||
|
||||
public String getDepositAddressFlashChannel() {
|
||||
return depositAddressFlashChannel;
|
||||
}
|
||||
|
||||
public int getDepositServerFlashChannelInIota() {
|
||||
return depositServerFlashChannelInIota;
|
||||
}
|
||||
|
||||
public int getDepositClientFlashChannelInIota() {
|
||||
return depositClientFlashChannelInIota;
|
||||
}
|
||||
|
||||
public String getFlashObject() {
|
||||
return flashObject;
|
||||
}
|
||||
|
||||
public String getClientRefundAddress() {
|
||||
return clientRefundAddress;
|
||||
}
|
||||
|
||||
public String getHotspotRefundAddress() {
|
||||
return hotspotRefundAddress;
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,14 +60,55 @@
|
||||
android:clickable="false"
|
||||
android:text="Flash channel" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/stopRoamingButton"
|
||||
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/channelFunded"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="STOP"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="10dp" />
|
||||
android:layout_marginBottom="10dp"
|
||||
android:checked="false"
|
||||
android:clickable="false"
|
||||
android:text="Channel funded" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginBottom="10dp" >
|
||||
|
||||
<Button
|
||||
android:id="@+id/stopRoamingButton"
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="STOP"
|
||||
/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/stopProgressBar"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="35dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/stopText"
|
||||
android:gravity="center"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/channelClosed"
|
||||
android:visibility="gone"/>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@ -75,6 +116,49 @@
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/card_view_tangle_attachment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="15dp"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"
|
||||
card_view:cardCornerRadius="4dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="15dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:text="Retransfer deposits"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressbarRetransfer"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="100"
|
||||
android:progress="5"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/retransferText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/initRetransfer"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/card_view_overview"
|
||||
@ -98,14 +182,14 @@
|
||||
android:textSize="20sp" />
|
||||
|
||||
|
||||
<TextView
|
||||
<ProgressBar
|
||||
android:id="@+id/progressbarMegabytes"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:id="@+id/summaryMinutes"
|
||||
android:text="0 minutes open"
|
||||
android:textSize="15sp" />
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/summaryMegabytes"
|
||||
@ -116,25 +200,44 @@
|
||||
android:text="0/0 Megabytes"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressbarDurance"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginTop="20dp"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:id="@+id/summaryMinutes"
|
||||
android:text="0/0 seconds"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressbarIota"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginTop="20dp"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/summaryIota"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:text="0 Iota transferred"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:text="0.1 Miota still locked"
|
||||
android:text="0/0 Iota transferred"
|
||||
android:textSize="15sp"
|
||||
android:layout_marginBottom="20dp"/>
|
||||
|
||||
|
||||
android:paddingBottom="20dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -142,6 +245,8 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.NoActionBar.PopupOverlay">
|
||||
<Switch
|
||||
<!--<Switch
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:layout_gravity="end"
|
||||
@ -27,7 +27,7 @@
|
||||
android:checked="false"
|
||||
android:hint="@string/wifi_p2p_discovery"
|
||||
android:width="120dp"
|
||||
android:id="@+id/wifiSwitch"/>
|
||||
android:id="@+id/wifiSwitch"/>-->
|
||||
</android.support.v7.widget.Toolbar>
|
||||
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
android:id="@+id/content_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:paddingTop="25dp"
|
||||
android:text="@string/hotspotIntroduction"
|
||||
android:textSize="20sp" />
|
||||
|
||||
@ -18,13 +19,15 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/startAP" />
|
||||
android:textOn="@string/stopAP"
|
||||
android:textOff="@string/startAPText" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressbarAP"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="25dp"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<TextView
|
||||
@ -32,6 +35,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:visibility="invisible"
|
||||
android:text="0 peers"
|
||||
android:textSize="30sp" />
|
||||
|
||||
|
||||
@ -34,7 +34,8 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left"
|
||||
android:layout_marginRight="50dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginRight="20dp"
|
||||
android:text="Device name"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Headline" />
|
||||
|
||||
@ -61,21 +62,14 @@
|
||||
<TextView android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:textColor="#000000"
|
||||
android:gravity="right"
|
||||
android:layout_weight="1"
|
||||
android:id="@+id/description"
|
||||
android:text="description"
|
||||
android:layout_marginRight="20dp"/>
|
||||
|
||||
<TextView android:textColor="#000000"
|
||||
android:id="@+id/ipAddr"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ipAddr"
|
||||
android:layout_marginRight="20dp"/>
|
||||
|
||||
<TextView android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_weight="0"
|
||||
android:textColor="#000000"
|
||||
android:id="@+id/iotaPrice"
|
||||
android:text="iotaPrice" />
|
||||
@ -83,6 +77,15 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressConnection"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -12,10 +12,10 @@
|
||||
android:id="@+id/nav_start"
|
||||
android:icon="@drawable/icon_tethering_on"
|
||||
android:title="@string/menuStartHotspot" />
|
||||
<item
|
||||
<!-- <item
|
||||
android:id="@+id/nav_itp"
|
||||
android:icon="@drawable/ic_highlight_black"
|
||||
android:title="@string/initialTrustPayment" />
|
||||
android:title="@string/initialTrustPayment" />-->
|
||||
|
||||
</group>
|
||||
|
||||
@ -32,12 +32,12 @@
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item android:title="Communicate">
|
||||
<item android:title="Conditions">
|
||||
<menu>
|
||||
<item
|
||||
<!-- <item
|
||||
android:id="@+id/nav_conditions"
|
||||
android:icon="@drawable/ic_compare_arrows"
|
||||
android:title="@string/navConditions" />
|
||||
android:title="@string/navConditions" />-->
|
||||
<item
|
||||
android:id="@+id/nav_settings"
|
||||
android:icon="@drawable/ic_menu_manage"
|
||||
|
||||
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 4.6 KiB |
18
app/src/main/res/values/connections.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="protocolPrivateTestnetNode">http</string>
|
||||
<string name="hostPrivateTestnetNode">87.118.96.200</string>
|
||||
<string name="portPrivateTestnetNode">14700</string>
|
||||
<string name="generatorPrivateTestnetNode">http://87.118.96.200:3000/</string>
|
||||
|
||||
<string name="protocolPublicTestnetNode">https</string>
|
||||
<string name="hostPublicTestnetNode">testnet140.tangle.works</string>
|
||||
<string name="portPublicTestnetNode">443</string>
|
||||
<string name="generatorPublicTestnetNode">https://hackseeds.tangle.works</string>
|
||||
|
||||
<string name="protocolDefaultMainnetNode">http</string>
|
||||
<string name="hostDefaultMainnetNode">node.iotawallet.info</string>
|
||||
<string name="portDefaultMainnetNode">14265</string>
|
||||
|
||||
</resources>
|
||||
20
app/src/main/res/values/errorCodes.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="err_no_finalization_received">No finalization received</string>
|
||||
<string name="err_pairing_roles_broken">Pairing roles are broken</string>
|
||||
<string name="no_hello_received">No hello received</string>
|
||||
<string name="err_no_offer_received">No offer received</string>
|
||||
<string name="err_buy_price_bad_setting">Buy price bad setting</string>
|
||||
<string name="err_price_too_high">Price too high</string>
|
||||
<string name="err_client_minutes_bad_setting">Client minutes bad setting</string>
|
||||
<string name="err_client_minutes_not_acceptable_for_hotspot">Client minutes not acceptable for hotspot</string>
|
||||
<string name="err_sell_price_bad_setting">Sell price bad setting</string>
|
||||
<string name="err_min_minutes_bad_setting">Min minutes bad setting</string>
|
||||
<string name="err_max_minutes_bad_setting">Max minutes bad setting</string>
|
||||
<string name="err_no_answer_received">No answer received</string>
|
||||
<string name="err_client_does_not_agree">Client does not agree to conditions</string>
|
||||
<string name="err_client_minutes_out_of_bounds">Client minutes is out of bounds</string>
|
||||
<string name="err_timeout">Timeout</string>
|
||||
<string name="err_io_exception">IO Exception</string>
|
||||
<string name="err_peer_quit">Peer quit the conversation</string>
|
||||
</resources>
|
||||
26
app/src/main/res/values/preferencesArrays.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="securityPref" >
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="networkTimeoutPref" >
|
||||
<item>15 seconds</item>
|
||||
<item>30 seconds</item>
|
||||
<item>1 minute</item>
|
||||
<item>3 minutes</item>
|
||||
<item>No timeout</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="unitsPref" >
|
||||
<item>Iota (i)</item>
|
||||
<item>Kilo Iota (Ki)</item>
|
||||
<item>Mega Iota (Mi)</item>
|
||||
<item>Giga Iota (Gi)</item>
|
||||
<item>Tera Iota (Ti)</item>
|
||||
<item>Peta Iota (Pi)</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
@ -1,5 +1,6 @@
|
||||
<resources>
|
||||
<string name="app_name">WifiP2P</string>
|
||||
<string name="app_version">1.0</string>
|
||||
<string name="title_activity_scrolling">ScrollingActivity</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="wifi_direct">Wifi Direct Chat</string>
|
||||
@ -64,5 +65,11 @@
|
||||
<string name="startSearch">Start Search</string>
|
||||
<string name="roaming_title">Roaming (This is your hotspot)</string>
|
||||
<string name="roaming_title_client">Roaming (You are consuming)</string>
|
||||
<string name="channelClosed">The payment channel was closed.</string>
|
||||
<string name="initRetransfer">Initializing retransfer</string>
|
||||
<string name="welcome">Welcome to the Wifi Iota Hotspot App</string>
|
||||
<string name="notification_doing_nothing">Currently doing nothing</string>
|
||||
<string name="stopAP">Stop Hotspot</string>
|
||||
<string name="startAPText">Start Hotspot</string>
|
||||
|
||||
</resources>
|
||||
158
app/src/main/res/xml/preferences.xml
Normal file
@ -0,0 +1,158 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="WiFi"
|
||||
android:key="pref_key_wifi_settings"
|
||||
android:elevation="10dp">
|
||||
|
||||
<Preference
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:key="pref_key_reset_data_usage"
|
||||
android:title="Reset data usage"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="IOTA"
|
||||
android:elevation="10dp"
|
||||
android:animateLayoutChanges="true"
|
||||
android:key="pref_key_IOTA_settings">
|
||||
|
||||
|
||||
<ListPreference
|
||||
android:key="pref_key_security"
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:defaultValue="2"
|
||||
android:entries="@array/securityPref"
|
||||
android:entryValues="@array/securityPref"
|
||||
android:title="Security pk/address" />
|
||||
|
||||
<ListPreference
|
||||
android:key="pref_key_network_timeout"
|
||||
android:entries="@array/networkTimeoutPref"
|
||||
android:entryValues="@array/networkTimeoutPref"
|
||||
android:title="Network timeout" />
|
||||
|
||||
<ListPreference
|
||||
android:key="pref_key_units"
|
||||
android:entries="@array/unitsPref"
|
||||
android:entryValues="@array/unitsPref"
|
||||
android:title="Units" />
|
||||
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="pref_key_switch_testnet"
|
||||
android:title="Testnet" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="pref_key_switch_testnet_private"
|
||||
android:title="Private testnet (recommended)" />
|
||||
|
||||
<Preference
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:key="pref_key_testnet_fund_add"
|
||||
android:title="Add 2000i testnet"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="Hotspot payment conditions"
|
||||
android:elevation="10dp"
|
||||
android:key="pref_key_payment_settings">
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="10"
|
||||
android:key="edit_text_sell_price"
|
||||
android:inputType="number"
|
||||
android:selectAllOnFocus="true"
|
||||
android:singleLine="true"
|
||||
android:title="Sell price" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="15"
|
||||
android:inputType="number"
|
||||
android:key="edit_text_sell_min_minutes"
|
||||
android:selectAllOnFocus="true"
|
||||
android:singleLine="true"
|
||||
android:title="Minimum sell duration (minutes)" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="100"
|
||||
android:key="edit_text_sell_max_minutes"
|
||||
android:inputType="number"
|
||||
android:selectAllOnFocus="true"
|
||||
android:singleLine="true"
|
||||
android:title="Maximum sell duration (minutes)" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="Client payment conditions"
|
||||
android:elevation="10dp"
|
||||
android:key="pref_key_payment_settings">
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="15"
|
||||
android:key="edit_text_buy_price"
|
||||
android:inputType="number"
|
||||
android:selectAllOnFocus="true"
|
||||
android:singleLine="true"
|
||||
android:title="Max buy price" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="60"
|
||||
android:key="edit_text_client_minutes"
|
||||
android:inputType="number"
|
||||
android:selectAllOnFocus="true"
|
||||
android:singleLine="true"
|
||||
android:title="Client roaming duration" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="Wallet"
|
||||
android:elevation="10dp"
|
||||
android:key="pref_key_wallet_settings">
|
||||
|
||||
<Preference
|
||||
android:key="pref_key_reset_password"
|
||||
android:title="Reset Password"/>
|
||||
|
||||
<Preference
|
||||
android:key="pref_key_reset_wallet"
|
||||
android:title="Reset Wallet"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="About"
|
||||
android:key="pref_key_about"
|
||||
android:elevation="10dp">
|
||||
|
||||
<Preference
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:key="pref_key_reset_version"
|
||||
android:title="@string/app_version"/>
|
||||
|
||||
<Preference
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:key="pref_key_license"
|
||||
android:title="License"/>
|
||||
|
||||
<Preference
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp"
|
||||
android:key="pref_key_agreement"
|
||||
android:title="Agreement"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||