From 12a7bc8c72cec8c8145aee4e26e679dd2bd57ea5 Mon Sep 17 00:00:00 2001 From: HappyZ Date: Wed, 25 Jan 2017 15:08:12 -0800 Subject: [PATCH] update tx normal tcp to new binary format TODO1: update all into a similar one TODO2: change cpu parser from 2 to any cores --- OffloadingDemo/mobile/mobile.iml | 16 + .../sandlab/offloadingdemo/MainActivity.java | 324 +++++++++++------- .../cs/sandlab/offloadingdemo/SSLogger.java | 17 +- .../offloadingdemo/Thread_TX_CNormal.java | 119 +++++-- .../cs/sandlab/offloadingdemo/Utilities.java | 145 +++++++- .../src/main/res/layout/activity_main.xml | 49 +-- .../mobile/src/main/res/values/strings.xml | 1 - OffloadingDemo/wear/wear.iml | 16 +- offloading_binaries/BypassL3_recv_lo/Makefile | 20 -- .../BypassL3_recv_lo/bypassl3_recv_lo | Bin 45804 -> 0 bytes offloading_binaries/BypassL3_recv_lo/main.c | 125 ------- offloading_binaries/BypassL3_recv_lo/main.o | Bin 3556 -> 0 bytes offloading_binaries/pushBinToDevice.sh | 24 -- preInstall4Mobile/pushBinToDevice.sh | 18 + preInstall4Mobile/tcpdump | Bin 0 -> 2041192 bytes 15 files changed, 499 insertions(+), 375 deletions(-) delete mode 100644 offloading_binaries/BypassL3_recv_lo/Makefile delete mode 100755 offloading_binaries/BypassL3_recv_lo/bypassl3_recv_lo delete mode 100644 offloading_binaries/BypassL3_recv_lo/main.c delete mode 100644 offloading_binaries/BypassL3_recv_lo/main.o delete mode 100755 offloading_binaries/pushBinToDevice.sh create mode 100755 preInstall4Mobile/pushBinToDevice.sh create mode 100644 preInstall4Mobile/tcpdump diff --git a/OffloadingDemo/mobile/mobile.iml b/OffloadingDemo/mobile/mobile.iml index 278e4d8..f15575d 100755 --- a/OffloadingDemo/mobile/mobile.iml +++ b/OffloadingDemo/mobile/mobile.iml @@ -82,7 +82,11 @@ + + + + @@ -109,11 +113,23 @@ + + + + + + + + + + + + diff --git a/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/MainActivity.java b/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/MainActivity.java index 618bd4a..8a2953f 100755 --- a/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/MainActivity.java +++ b/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/MainActivity.java @@ -30,8 +30,11 @@ import java.util.Date; public class MainActivity extends Activity { // unchanged stuff - protected static final String sshlinklab = "ssh linklab@hotcrp.cs.ucsb.edu -i /data/.ssh/id_rsa -o StrictHostKeyChecking=no"; - protected static final String sshlinklablocal = "ssh linklab@128.111.68.220 -i /data/.ssh/id_rsa -o StrictHostKeyChecking=no"; + protected static final String remoteIP = "128.111.68.220"; + protected static final String sshlinklab = "ssh linklab@hotcrp.cs.ucsb.edu" + + " -i /data/.ssh/id_rsa -o StrictHostKeyChecking=no"; + protected static final String sshlinklablocal = "ssh linklab@" + remoteIP + + " -i /data/.ssh/id_rsa -o StrictHostKeyChecking=no"; protected static final String udpserver_pathport = "~/mobileRDMABeach/UDPServer 32000 "; protected static final String binaryFolderPath = "/data/local/tmp/"; protected static final String binary_tcpdump = "tcpdump"; @@ -62,24 +65,25 @@ public class MainActivity extends Activity { protected static double reportedFinishTime = 0.0; protected static int repeatCounts = 3; protected static int bytes2send = 10*oneMB; // default 10MB - protected static int currentBandwidth = 20000000; // bytes per sec, default unlimited (not for loopback) + protected static int currentBandwidth = -1; // bps, default is -1, indicating unlimited protected static TextView txt_results; protected static Handler myHandler; - protected static String RXportNum = "4445"; + protected static String myInetIP = ""; + protected static String RXportNum = "4444"; protected static String outFolderPath; protected static String btn_click_time; protected static String tcpdumpInterface = "wlan0"; - protected static String binary_TX_Normal = "normal"; - protected static String binary_TX_NormalUDP = "normal_udp"; - protected static String binary_TX_Sendfile = "sendfile"; - protected static String binary_TX_Splice = "splice"; - protected static String binary_TX_RawNormal = "bypassl3"; + protected static String binary_TX_Normal; + protected static String binary_TX_NormalUDP; + protected static String binary_TX_Sendfile; + protected static String binary_TX_Splice; + protected static String binary_TX_RawNormal; protected static final String binary_TX_RawSplice = ""; - protected static String binary_RX_Normal = "normal_recv"; - protected static String binary_RX_NormalUDP = "normal_udp_recv"; + protected static String binary_RX_Normal; + protected static String binary_RX_NormalUDP; protected static final String binary_RX_Sendfile = ""; - protected static String binary_RX_Splice = "splice_recv"; - protected static String binary_RX_RawNormal = "bypassl3_recv"; + protected static String binary_RX_Splice; + protected static String binary_RX_RawNormal; protected static boolean isUsingWifi = true; protected static boolean isRunning_TX_Normal = false; protected static boolean isRunning_TX_NormalUDP = false; @@ -99,7 +103,8 @@ public class MainActivity extends Activity { */ protected boolean isServiceRunning(Class serviceClass) { ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); - for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { + for (ActivityManager.RunningServiceInfo service : manager.getRunningServices( + Integer.MAX_VALUE)) { if (serviceClass.getName().equals(service.service.getClassName())) { return true; } @@ -119,45 +124,61 @@ public class MainActivity extends Activity { } } + private void killAllBinaries() { + try { + Runtime.getRuntime().exec("su -c killall -9 " + binary_TX_Normal).waitFor(); + Runtime.getRuntime().exec("su -c killall -9 " + binary_TX_NormalUDP).waitFor(); + Runtime.getRuntime().exec("su -c killall -9 " + binary_TX_Sendfile).waitFor(); + Runtime.getRuntime().exec("su -c killall -9 " + binary_TX_Splice).waitFor(); + Runtime.getRuntime().exec("su -c killall -9 " + binary_TX_RawNormal).waitFor(); + Runtime.getRuntime().exec("su -c killall -9 " + binary_RX_Normal).waitFor(); + Runtime.getRuntime().exec("su -c killall -9 " + binary_RX_NormalUDP).waitFor(); + Runtime.getRuntime().exec("su -c killall -9 " + binary_RX_Splice).waitFor(); + Runtime.getRuntime().exec("su -c killall -9 " + binary_RX_RawNormal).waitFor(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + private boolean checkBinaryFilesExist() { String missingFiles = ""; if (!Utilities.fileExist(binaryFolderPath + binary_tcpdump)) missingFiles += binary_tcpdump; if (!Utilities.fileExist(binaryFolderPath + binary_TX_Normal)) missingFiles += " " + binary_TX_Normal; - if (!Utilities.fileExist(binaryFolderPath + binary_TX_Normal + "_lo")) - missingFiles += " " + binary_TX_Normal + "_lo"; if (!Utilities.fileExist(binaryFolderPath + binary_TX_NormalUDP)) missingFiles += " " + binary_TX_NormalUDP; - if (!Utilities.fileExist(binaryFolderPath + binary_TX_NormalUDP + "_lo")) - missingFiles += " " + binary_TX_NormalUDP + "_lo"; if (!Utilities.fileExist(binaryFolderPath + binary_TX_Sendfile)) missingFiles += " " + binary_TX_Sendfile; - if (!Utilities.fileExist(binaryFolderPath + binary_TX_Sendfile + "_lo")) - missingFiles += " " + binary_TX_Sendfile + "_lo"; if (!Utilities.fileExist(binaryFolderPath + binary_TX_Splice)) missingFiles += " " + binary_TX_Splice; if (!Utilities.fileExist(binaryFolderPath + binary_TX_RawNormal)) missingFiles += " " + binary_TX_RawNormal; - if (!Utilities.fileExist(binaryFolderPath + binary_TX_RawNormal + "_lo")) - missingFiles += " " + binary_TX_RawNormal + "_lo"; if (!Utilities.fileExist(binaryFolderPath + binary_RX_Normal)) missingFiles += " " + binary_RX_Normal; - if (!Utilities.fileExist(binaryFolderPath + binary_RX_Normal + "_lo")) - missingFiles += " " + binary_RX_Normal + "_lo"; if (!Utilities.fileExist(binaryFolderPath + binary_RX_NormalUDP)) missingFiles += " " + binary_RX_NormalUDP; - if (!Utilities.fileExist(binaryFolderPath + binary_RX_NormalUDP + "_lo")) - missingFiles += " " + binary_RX_NormalUDP + "_lo"; if (!Utilities.fileExist(binaryFolderPath + binary_RX_Splice)) missingFiles += " " + binary_RX_Splice; - if (!Utilities.fileExist(binaryFolderPath + binary_RX_Splice + "_lo")) - missingFiles += " " + binary_RX_Splice + "_lo"; if (!Utilities.fileExist(binaryFolderPath + binary_RX_RawNormal)) missingFiles += " " + binary_RX_RawNormal; - if (!Utilities.fileExist(binaryFolderPath + binary_RX_RawNormal + "_lo")) - missingFiles += " " + binary_RX_RawNormal + "_lo"; - + if (!Utilities.fileExist(binaryFolderPath + "bigfile")) { + try { + Runtime.getRuntime().exec( + "dd if=/dev/zero of=" + + binaryFolderPath + "bigfile" + + " count=1 bs=1 seek=$((2 * 1024 * 1024 * 1024 - 1))").waitFor(); + Runtime.getRuntime().exec( + "chmod 755 " + binaryFolderPath + "bigfile"); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + Toast.makeText(this, "Created a 2Gbits big file", Toast.LENGTH_LONG).show(); + } if (!missingFiles.equals("")) { final String mFiles = missingFiles; myHandler.post(new Runnable() { @@ -183,6 +204,7 @@ public class MainActivity extends Activity { protected void startRecording(boolean myflag) { final boolean flagRecv = myflag; final ArrayList selectedItems = new ArrayList<>(); + AlertDialog.Builder adb = new AlertDialog.Builder(MainActivity.this); adb.setMultiChoiceItems(existedItems, null, new DialogInterface.OnMultiChoiceClickListener() { @Override @@ -198,12 +220,14 @@ public class MainActivity extends Activity { } } }); + adb.setPositiveButton("Continue", new DialogInterface.OnClickListener() { // Process su = null; @Override public void onClick(DialogInterface dialog, int which) { if (selectedItems.size() < 1) { - Toast.makeText(MainActivity.this, "Nothing is selected", Toast.LENGTH_SHORT).show(); + Toast.makeText(MainActivity.this, "Nothing is selected", Toast.LENGTH_SHORT) + .show(); return; } final ArrayList selectedItemsThrpt = new ArrayList<>(); @@ -222,18 +246,21 @@ public class MainActivity extends Activity { @Override public void onClick(DialogInterface dialog, int which) { if (selectedItemsThrpt.size() < 1) { - Toast.makeText(MainActivity.this, "Nothing is selected", Toast.LENGTH_SHORT).show(); + Toast.makeText( + MainActivity.this, "Nothing is selected", Toast.LENGTH_SHORT) + .show(); return; } if (isVerbose) { Log.d(TAG, "selected variations " + selectedItemsThrpt); } - Utilities.estimateTime(repeatCounts, selectedItems.size(), bytes2send, selectedItemsThrpt); + Utilities.estimateTime( + repeatCounts, selectedItems.size(), bytes2send, selectedItemsThrpt); // power management PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); - final PowerManager.WakeLock wakelock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - "MyWakelockTag"); + final PowerManager.WakeLock wakelock = powerManager.newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, "MyWakelockTag"); new Thread(new Runnable() { @Override @@ -241,14 +268,16 @@ public class MainActivity extends Activity { String[] commd = new String[3]; commd[0] = "su"; commd[1] = "&&"; -// wakelock.acquire(); + wakelock.acquire(); // change screen brightness to 0 // Settings.System.putInt(MainActivity.this.getContentResolver(), // Settings.System.SCREEN_BRIGHTNESS, 0); -// final WindowManager.LayoutParams lp = getWindow().getAttributes(); -// lp.screenBrightness = 0.0f;// 100 / 100.0f; + final WindowManager.LayoutParams lp = getWindow().getAttributes(); + lp.screenBrightness = 0.0f;// 100 / 100.0f; try { - Runtime.getRuntime().exec("su -c echo 0 > /sys/class/lcd/panel/lcd_power").waitFor(); + Runtime.getRuntime().exec( + "su -c echo 0 > /sys/class/lcd/panel/lcd_power") + .waitFor(); } catch (InterruptedException e) { e.printStackTrace(); } catch (IOException e) { @@ -263,41 +292,28 @@ public class MainActivity extends Activity { }); // prepare try { - Runtime.getRuntime().exec("su -c killall -9 normal").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 normal_lo").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 normal_udp").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 normal_udp_lo").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 sendfile").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 sendfile_lo").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 splice").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 splice_lo").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 bypassl3").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 bypassl3_lo").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 normal_recv").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 normal_recv_lo").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 normal_udp_recv").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 normal_udp_recv_lo").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 splice_recv").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 splice_recv_lo").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 bypassl3_recv").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 bypassl3_recv_lo").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 tcpdump").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 TCPReceiver_mobile").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 TCPSender_mobile").waitFor(); - Runtime.getRuntime().exec("su -c killall -9 UDPServer_mobile").waitFor(); - if (isLocal) { - if (flagRecv) - Runtime.getRuntime().exec("su && /data/local/tmp/Run_for_Download.sh").waitFor(); - else - Runtime.getRuntime().exec("su && /data/local/tmp/Run_for_Upload.sh").waitFor(); - } else { - myHandler.post(new Runnable() { - @Override - public void run() { - MainActivity.txt_results.append("In case you forget, remember to run " + ((flagRecv) ? "Run_for_Download.sh" : "Run_for_Upload.sh") + "\n"); - } - }); - } + killAllBinaries(); + Runtime.getRuntime().exec( + "su -c killall -9 " + binary_tcpdump).waitFor(); + Runtime.getRuntime().exec( + "su -c killall -9 TCPReceiver_mobile").waitFor(); + Runtime.getRuntime().exec( + "su -c killall -9 TCPSender_mobile").waitFor(); + Runtime.getRuntime().exec( + "su -c killall -9 UDPServer_mobile").waitFor(); +// if (isLocal) { +// if (flagRecv) +// Runtime.getRuntime().exec("su && /data/local/tmp/Run_for_Download.sh").waitFor(); +// else +// Runtime.getRuntime().exec("su && /data/local/tmp/Run_for_Upload.sh").waitFor(); +// } else { +// myHandler.post(new Runnable() { +// @Override +// public void run() { +// MainActivity.txt_results.append("In case you forget, remember to run " + ((flagRecv) ? "Run_for_Download.sh" : "Run_for_Upload.sh") + "\n"); +// } +// }); +// } } catch (InterruptedException e) { e.printStackTrace(); } catch (IOException e) { @@ -307,7 +323,7 @@ public class MainActivity extends Activity { for (int k = 0; k < selectedItemsThrpt.size(); ++k) { int myI = selectedItemsThrpt.get(k); currentBandwidth = Utilities.findCorrespondingThrpt(myI); - RXportNum = Integer.toString(4445 - myI + 24); +// RXportNum = Integer.toString(4445 - myI + 24); if (isVerbose) { Log.d(TAG, "bandwidth is set to " + currentBandwidth + "\nRXportNum is set to " + RXportNum); @@ -319,7 +335,8 @@ public class MainActivity extends Activity { Runtime.getRuntime().exec(commd).waitFor(); commd[2] = "mkdir -p"; for (int i = 0; i < selectedItems.size(); ++i) { - commd[2] += " " + outFolderPath + "/" + existedItems[selectedItems.get(i)]; + commd[2] += " " + outFolderPath + "/" + + existedItems[selectedItems.get(i)]; } Runtime.getRuntime().exec(commd).waitFor(); Thread.sleep(1000); @@ -460,19 +477,25 @@ public class MainActivity extends Activity { } // parse and zip it for (int i = 0; i < selectedItems.size(); ++i) { - if (Utilities.parseCPUforFolder((String) existedItems[selectedItems.get(i)])) { - String tarName = ((flagRecv) ? "download_" : "upload_") + if (Utilities.parseCPUforFolder( + (String) existedItems[selectedItems.get(i)])) { + String tarName = ( + (flagRecv) ? "download_" : "upload_") + existedItems[selectedItems.get(i)] + "_" - + (bytes2send / 1024) + "KB_" + repeatCounts + "repeats_thrpt_" + + (bytes2send / 1024) + "KB_" + + repeatCounts + "repeats_thrpt_" + (currentBandwidth / 1000000.0) + "MBps_" - + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + + new SimpleDateFormat("yyyyMMdd_HHmmss") + .format(new Date()) + ".tar.gz"; commd[2] = "cd " + outFolderPath + "/" + existedItems[selectedItems.get(i)] - + " && busybox tar -czf ../" + tarName + " *"; + + " && busybox tar -czf ../" + + tarName + " *"; Runtime.getRuntime().exec(commd).waitFor(); } else { - final CharSequence failedFolderName = existedItems[selectedItems.get(i)]; + final CharSequence failedFolderName = + existedItems[selectedItems.get(i)]; myHandler.post(new Runnable() { @Override public void run() { @@ -489,23 +512,26 @@ public class MainActivity extends Activity { e.printStackTrace(); } } -// wakelock.release(); // change screen brightness back + wakelock.release(); // Settings.System.putInt(MainActivity.this.getContentResolver(), // Settings.System.SCREEN_BRIGHTNESS, 200); -// lp.screenBrightness = 50;// 50 / 100.0f; + lp.screenBrightness = 50;// 50 / 100.0f; try { - Runtime.getRuntime().exec("su -c echo 1 > /sys/class/lcd/panel/lcd_power").waitFor(); + Runtime.getRuntime().exec( + "su -c echo 1 > /sys/class/lcd/panel/lcd_power") + .waitFor(); } catch (InterruptedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } + // msg indicating all done myHandler.post(new Runnable() { @Override public void run() { txt_results.append("All Done\n"); -// getWindow().setAttributes(lp); + getWindow().setAttributes(lp); } }); } @@ -527,13 +553,26 @@ public class MainActivity extends Activity { // must have root privilege in order to run try { Runtime.getRuntime().exec("su"); + Toast.makeText(MainActivity.this, "Remember to silent SuperUser", Toast.LENGTH_SHORT) + .show(); } catch (Throwable e) { Toast.makeText(this, R.string.warn_root, Toast.LENGTH_LONG).show(); } + // must have storage permission + Utilities.verifyStoragePermissions(this); // handler that updates the ui at main thread // it's used in sslogger thus will be modded in receiver activity also // do not modify this myHandler = new Handler(); + // sslogger intent + intentSSLogger = new Intent(this, SSLogger.class); + // grab WiFi service and check if wifi is enabled + wm = (WifiManager) this.getSystemService(WIFI_SERVICE); + isUsingWifi = (wm.isWifiEnabled()) ? true : false; + if (isUsingWifi) { + myInetIP = Utilities.getInetIP(true); + } + // predefined selections existedItems = new CharSequence[] { "Socket_Normal", "Socket_NormalUDP", "Socket_Sendfile", "Socket_Splice", "RawSocket_Normal" @@ -548,22 +587,24 @@ public class MainActivity extends Activity { "95MB", "100MB", // 41-42 "11MB", "13MB" // 43-44 }; - intentSSLogger = new Intent(this, SSLogger.class); - wm = (WifiManager) this.getSystemService(WIFI_SERVICE); - // assignments - binary_TX_Normal = "normal"; - binary_TX_NormalUDP = "normal_udp"; - binary_TX_Sendfile = "sendfile"; - binary_TX_RawNormal = "bypassl3"; - binary_TX_Splice = "splice"; - binary_RX_Normal = "normal_recv"; - binary_RX_NormalUDP = "normal_udp_recv"; - binary_RX_Splice = "splice_recv"; - binary_RX_RawNormal = "bypassl3_recv"; + // binary executables to run + binary_TX_Normal = "client_send_normaltcp"; + binary_TX_NormalUDP = "client_send_normaludp"; + binary_TX_Sendfile = "client_send_normaltcp_sendfile"; + binary_TX_RawNormal = "client_send_bypassl3"; + binary_TX_Splice = "client_send_normaltcp_splice"; + binary_RX_Normal = "client_recv_normaltcp"; + binary_RX_NormalUDP = "client_recv_normaludp"; + binary_RX_Splice = "client_recv_normaltcp_splice"; + binary_RX_RawNormal = "client_recv_bypassl3"; + // get number of cores coreNum = Utilities.getNumCores(); + // output folder for SSLogger outFolderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SSLogger"; - isUsingWifi = (wm.isWifiEnabled())?true:false; - // find view elements + if (!Utilities.dirExist(outFolderPath, true)) { + Toast.makeText(this, "Cannot create folder!!!", Toast.LENGTH_LONG).show(); + } + // elements in the page txt_results = (TextView) findViewById(R.id.txt_results); btn_startTransmit = (Button) findViewById(R.id.btn_startTransmit); btn_startReceive = (Button) findViewById(R.id.btn_startReceive); @@ -574,8 +615,11 @@ public class MainActivity extends Activity { btn_setLogFreq = (Button) findViewById(R.id.btn_setLogFreq); btn_clearStatus = (Button) findViewById(R.id.btn_clearStatus); if (coreNum > 2) { - txt_results.append("Only support 2 cores now! Contact Yanzi to add "+coreNum+" cores support!\n"); + txt_results.append( + "Only support 2 cores now! Contact Yanzi to add " + + coreNum + " cores support!\n"); } + // TODO: remember to add more than 2 core support txt_results.append(isUsingWifi?getString(R.string.stat_wifion):getString(R.string.stat_wifioff)); // click listener btn_startTransmit.setOnClickListener(new View.OnClickListener() { @@ -701,7 +745,8 @@ public class MainActivity extends Activity { } else { tcpdumpInterface = ((String) mTmp[which]).replace("Current: ", ""); isUsingTCPDump = true; - Toast.makeText(MainActivity.this, "TCPDump interface is changed to " + tcpdumpInterface, Toast.LENGTH_SHORT).show(); + Toast.makeText(MainActivity.this, "TCPDump interface is changed to " + + tcpdumpInterface, Toast.LENGTH_SHORT).show(); if (isVerbose) { Log.d(TAG, "TCPDump interface is set to " + tcpdumpInterface); } @@ -714,8 +759,13 @@ public class MainActivity extends Activity { btn_setOthers.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - CharSequence[] items = {"Verbose Mode", "Only Run Locally", "CPULog (Per Proc)", "CPULog (WiFi Driver)", "CPULog (This App)", "CPULog (TCPDump)", "Force on CPU0"}; - boolean[] checkedItems = {isVerbose, isLocal, isLoggingPerProcPID, (wifiDriverPID!=-1), isLoggingAppSelf, isLoggingTCPDump, isForcingCPU0}; + CharSequence[] items = { + "Verbose Mode", "Only Run Locally", "CPULog (Per Proc)", + "CPULog (WiFi Driver)", "CPULog (This App)", "CPULog (TCPDump)", + "Force on CPU0"}; + boolean[] checkedItems = { + isVerbose, isLocal, isLoggingPerProcPID, (wifiDriverPID!=-1), + isLoggingAppSelf, isLoggingTCPDump, isForcingCPU0}; AlertDialog.Builder adb = new AlertDialog.Builder(MainActivity.this); adb.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() { @Override @@ -723,48 +773,71 @@ public class MainActivity extends Activity { switch (which) { case 0: isVerbose = isChecked; - Toast.makeText(MainActivity.this, "Set to be " + (isVerbose ? "verbose" : "NOT verbose"), Toast.LENGTH_SHORT).show(); + Toast.makeText(MainActivity.this, "Set to be " + + (isVerbose ? "verbose" : "NOT verbose"), + Toast.LENGTH_SHORT).show(); break; case 1: isLocal = isChecked; - binary_TX_Normal = isLocal ? "normal_lo" : "normal"; - binary_TX_NormalUDP = isLocal ? "normal_udp_lo" : "normal_udp"; - binary_TX_Sendfile = isLocal ? "sendfile_lo" : "sendfile"; - binary_TX_Splice = isLocal ? "splice_lo" : "splice"; - binary_TX_RawNormal = isLocal ? "bypassl3_lo" : "bypassl3"; - binary_RX_Normal = isLocal ? "normal_recv_lo" : "normal_recv"; - binary_RX_NormalUDP = isLocal ? "normal_udp_recv_lo" : "normal_udp_recv"; - binary_RX_Splice = isLocal ? "splice_recv_lo" : "splice_recv"; - binary_RX_RawNormal = isLocal ? "bypassl3_recv_lo" : "bypassl3_recv"; +// binary_TX_Normal = isLocal ? "normal_lo" : "normal"; +// binary_TX_NormalUDP = isLocal ? "normal_udp_lo" : "normal_udp"; +// binary_TX_Sendfile = isLocal ? "sendfile_lo" : "sendfile"; +// binary_TX_Splice = isLocal ? "splice_lo" : "splice"; +// binary_TX_RawNormal = isLocal ? "bypassl3_lo" : "bypassl3"; +// binary_RX_Normal = isLocal ? "normal_recv_lo" : "normal_recv"; +// binary_RX_NormalUDP = +// isLocal ? "normal_udp_recv_lo" : "normal_udp_recv"; +// binary_RX_Splice = isLocal ? "splice_recv_lo" : "splice_recv"; +// binary_RX_RawNormal = +// isLocal ? "bypassl3_recv_lo" : "bypassl3_recv"; if (isLocal) { isUsingTCPDump = false; - Toast.makeText(MainActivity.this, "Remember to set IP to 192.168.1.15\n" + - "Will start TCPSdr/Rcvr locally\ntcpdump disabled", Toast.LENGTH_LONG).show(); + Toast.makeText(MainActivity.this, + "Remember to set IP to 192.168.1.15\n" + + "Will start locally\n" + + "tcpdump disabled", Toast.LENGTH_LONG).show(); } else { isUsingTCPDump = true; tcpdumpInterface = "wlan0"; - Toast.makeText(MainActivity.this, "Back to original\ntcpdump enabled to wlan0", Toast.LENGTH_LONG).show(); + Toast.makeText(MainActivity.this, + "Back to original\ntcpdump enabled to wlan0", + Toast.LENGTH_LONG).show(); } break; case 2: isLoggingPerProcPID = isChecked; - Toast.makeText(MainActivity.this, isLoggingPerProcPID?"Will log per process cpu":"Will NOT log per process cpu", Toast.LENGTH_SHORT).show(); + Toast.makeText(MainActivity.this, + isLoggingPerProcPID ? + "Will log cpu/process" : "cpu/process disabled", + Toast.LENGTH_SHORT).show(); break; case 3: - wifiDriverPID = isChecked?Utilities.getMyPID("dhd_dpc", true):-1; - Toast.makeText(MainActivity.this, (wifiDriverPID!=-1)?"Will log wifi driver cpu":"Will NOT log wifi driver cpu", Toast.LENGTH_SHORT).show(); + wifiDriverPID = isChecked ? + Utilities.getMyPID("dhd_dpc", true) : -1; + Toast.makeText(MainActivity.this, + (wifiDriverPID != -1) ? + "Will log wifi driver cpu" : "wifi driver cpu disabled", + Toast.LENGTH_SHORT).show(); break; case 4: isLoggingAppSelf = isChecked; - Toast.makeText(MainActivity.this, isLoggingAppSelf?"Will log app itself cpu":"Will NOT log app itself cpu", Toast.LENGTH_SHORT).show(); + Toast.makeText(MainActivity.this, + isLoggingAppSelf ? + "Will log app cpu" : "Will NOT log app cpu", + Toast.LENGTH_SHORT).show(); break; case 5: isLoggingTCPDump = isChecked; - Toast.makeText(MainActivity.this, isLoggingTCPDump?"Will log tcpdump cpu":"Will NOT log tcpdump cpu", Toast.LENGTH_SHORT).show(); + Toast.makeText(MainActivity.this, + isLoggingTCPDump ? + "Will log tcpdump cpu" : "Will NOT log tcpdump cpu", + Toast.LENGTH_SHORT).show(); break; case 6: isForcingCPU0 = isChecked; - Toast.makeText(MainActivity.this, (isForcingCPU0?"Force running on cpu 0":"Will run on any cpu"), Toast.LENGTH_SHORT).show(); + Toast.makeText(MainActivity.this, + (isForcingCPU0 ? "Force on cpu 0" : "Will run on any cpu"), + Toast.LENGTH_SHORT).show(); break; } } @@ -820,7 +893,8 @@ public class MainActivity extends Activity { myHandler.post(new Runnable() { @Override public void run() { - MainActivity.txt_results.append("time_wait_for is set to " + time_wait_for + "ms\n"); + MainActivity.txt_results.append( + "time_wait_for is set to " + time_wait_for + "ms\n"); } }); Log.d(TAG, "time_wait_for is set to " + time_wait_for + "ms"); diff --git a/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/SSLogger.java b/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/SSLogger.java index c673602..54d0deb 100755 --- a/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/SSLogger.java +++ b/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/SSLogger.java @@ -89,8 +89,10 @@ public class SSLogger extends Service { ssStuff = (mTime + " wifi " + wifiRSS + "\n").getBytes(); try { if (isRunning) { - if (wifiRSS != 0) + if (wifiRSS != 0) { +// Log.d(TAG, "Wrote stuff: " + ssStuff); os_ss.write(ssStuff); + } os_cpu.write(cpuStuff); if (MainActivity.wifiDriverPID != -1) os_cpuWiFiDriverPID.write(cpuWiFiDriverPIDStuff); @@ -164,9 +166,11 @@ public class SSLogger extends Service { } // create folder File mDir = new File(MainActivity.outFolderPath); - mDir.mkdir(); - if (wifiRSS != 0) +// mDir.mkdir(); + if (wifiRSS != 0) { +// Log.d(TAG, "wifi rss is not 0"); ssFileName = MainActivity.btn_click_time.concat(".ss"); + } cpuFileName = MainActivity.btn_click_time.concat(".cpuRaw"); if (MainActivity.wifiDriverPID != -1) cpuWiFiDriverPIDFileName = MainActivity.btn_click_time.concat(".cpuPID"); @@ -177,8 +181,11 @@ public class SSLogger extends Service { if (MainActivity.isLoggingAppSelf) cpuAppSelfFileName = MainActivity.btn_click_time.concat(".cpuAppSelf"); try { - if (wifiRSS != 0) - os_ss = new FileOutputStream(new File(mDir, ssFileName)); + if (wifiRSS != 0) { +// Log.d(TAG, "create os_ss handler"); + File tmp = new File(mDir, ssFileName); + os_ss = new FileOutputStream(tmp); + } os_cpu = new FileOutputStream(new File(mDir, cpuFileName)); if (MainActivity.wifiDriverPID != -1) os_cpuWiFiDriverPID = new FileOutputStream(new File(mDir, cpuWiFiDriverPIDFileName)); diff --git a/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/Thread_TX_CNormal.java b/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/Thread_TX_CNormal.java index 559cc1e..5d0745c 100755 --- a/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/Thread_TX_CNormal.java +++ b/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/Thread_TX_CNormal.java @@ -2,13 +2,20 @@ package edu.ucsb.cs.sandlab.offloadingdemo; import android.util.Log; +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; /** * Created by yanzi on 9/18/15. + * Updated on 01/25/17 */ public class Thread_TX_CNormal implements Runnable { + private double sentBytes = 0.0; + private double duration = 0.0; + private double throughput = 0.0; + @Override public void run() { if (MainActivity.isRunning_TX_Normal) @@ -18,51 +25,105 @@ public class Thread_TX_CNormal implements Runnable { MainActivity.isRunning_TX_Normal = true; Process proc; String[] commd = new String[3]; + + // get the right command commd[0] = "su"; commd[1] = "-c"; + // ./client_send_normaltcp + // <[optional] bandwidth (bps)> <[optional] sendsize (bytes)> commd[2] = (MainActivity.isForcingCPU0?"taskset 1 ":"") + MainActivity.binaryFolderPath + MainActivity.binary_TX_Normal + " " - + MainActivity.bytes2send + " " + String.valueOf(MainActivity.currentBandwidth); + + MainActivity.bytes2send + " " + + (MainActivity.isLocal ? MainActivity.myInetIP : MainActivity.remoteIP) + " " + + MainActivity.RXportNum + " " + + ((MainActivity.currentBandwidth < 0) ? "" : String.valueOf( + MainActivity.currentBandwidth)); + try { + // run process proc = Runtime.getRuntime().exec(commd); + + // if config to log per process while (MainActivity.isLoggingPerProcPID && MainActivity.perProcPID == -1) { -// Log.d("Thread_TX_CNormal", "per proc: " + MainActivity.perProcPID); MainActivity.perProcPID = Utilities.getMyPID(MainActivity.binary_TX_Normal, false); } proc.waitFor(); - InputStream stdout = proc.getInputStream(); - byte[] buffer = new byte[20]; - int read; - StringBuilder out = new StringBuilder(); - while(true){ - read = stdout.read(buffer); - if(read<0){ - MainActivity.myHandler.post(new Runnable() { - @Override - public void run() { - MainActivity.txt_results.append("Failed in TX_Normal\n"); - } - }); - break; - } - out.append(new String(buffer, 0, read)); - if(read<20){ - break; - } - } - final String mOut = out.toString().trim(); - if (mOut != "") - MainActivity.reportedFinishTime = Double.parseDouble(mOut); - else - MainActivity.reportedFinishTime = 0.0; - if (MainActivity.isVerbose) { + + // read error + BufferedReader error_buf = new BufferedReader(new InputStreamReader( + proc.getErrorStream())); + final String error = error_buf.readLine(); // only one line error + + // read std out + BufferedReader stdout_buf = new BufferedReader(new InputStreamReader( + proc.getInputStream())); + String stdout; + + // get sent bytes + stdout = stdout_buf.readLine(); + if (stdout == null) { + // error happens MainActivity.myHandler.post(new Runnable() { @Override public void run() { - MainActivity.txt_results.append("Time: " + mOut + "ms\n"); + MainActivity.txt_results.append("Err in TX_Normal: " + error + "\n"); } }); + } else { + // sent bytes + sentBytes = Utilities.parseBinOutput(stdout); + + // duration + stdout = stdout_buf.readLine(); + duration = Utilities.parseBinOutput(stdout); + MainActivity.reportedFinishTime = duration; + if (MainActivity.isVerbose) { + MainActivity.myHandler.post(new Runnable() { + @Override + public void run() { + MainActivity.txt_results.append("Time: " + duration + "ms\n"); + } + }); + } + + // throughput + stdout = stdout_buf.readLine(); + throughput = Utilities.parseBinOutput(stdout); } + +// InputStream stdout = proc.getInputStream(); +// byte[] buffer = new byte[20]; +// int read; +// StringBuilder out = new StringBuilder(); +// while(true){ +// read = stdout.read(buffer); +// if(read<0){ +// MainActivity.myHandler.post(new Runnable() { +// @Override +// public void run() { +// MainActivity.txt_results.append("Err in TX_Normal: " + error + "\n"); +// } +// }); +// break; +// } +// out.append(new String(buffer, 0, read)); +// if(read<20){ +// break; +// } +// } +// final String mOut = out.toString().trim(); +// if (!mOut.equals("")) +// MainActivity.reportedFinishTime = Double.parseDouble(mOut); +// else +// MainActivity.reportedFinishTime = 0.0; +// if (MainActivity.isVerbose) { +// MainActivity.myHandler.post(new Runnable() { +// @Override +// public void run() { +// MainActivity.txt_results.append("Time: " + mOut + "ms\n"); +// } +// }); +// } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { diff --git a/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/Utilities.java b/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/Utilities.java index b1a19cf..d50f813 100755 --- a/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/Utilities.java +++ b/OffloadingDemo/mobile/src/main/java/edu/ucsb/cs/sandlab/offloadingdemo/Utilities.java @@ -1,6 +1,10 @@ package edu.ucsb.cs.sandlab.offloadingdemo; +import android.Manifest; +import android.app.Activity; +import android.content.pm.PackageManager; import android.os.Environment; +import android.support.v4.app.ActivityCompat; import android.util.Log; import java.io.BufferedReader; @@ -10,15 +14,49 @@ import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.UnknownHostException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; +import java.util.List; /** * Created by yanzi on 10/1/15. */ public class Utilities { private static final String TAG = "Utilities"; + // Storage Permissions + private static final int REQUEST_EXTERNAL_STORAGE = 1; + private static String[] PERMISSIONS_STORAGE = { + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE + }; + + /** + * Checks if the app has permission to write to device storage + * + * If the app does not has permission then the user will be prompted to grant permissions + * + * @param activity + */ + public static void verifyStoragePermissions(Activity activity) { + // Check if we have write permission + int permission = ActivityCompat.checkSelfPermission( + activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); + + if (permission != PackageManager.PERMISSION_GRANTED) { + // We don't have permission so prompt the user + ActivityCompat.requestPermissions( + activity, + PERMISSIONS_STORAGE, + REQUEST_EXTERNAL_STORAGE + ); + } + } + /** * check if we can write on external storage @@ -32,6 +70,51 @@ public class Utilities { return false; } + /** + * get the ip address + * @return str + */ + protected static String getInetIP(boolean useIPv4) { + try { + List interfaces = Collections.list( + NetworkInterface.getNetworkInterfaces()); + for (NetworkInterface intf : interfaces) { + List addrs = Collections.list(intf.getInetAddresses()); + for (InetAddress addr : addrs) { + if (!addr.isLoopbackAddress()) { + String sAddr = addr.getHostAddress(); + //boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr); + boolean isIPv4 = sAddr.indexOf(':')<0; + + if (useIPv4) { + if (isIPv4) + return sAddr; + } else { + if (!isIPv4) { + int delim = sAddr.indexOf('%'); // drop ip6 zone suffix + return delim<0 ? sAddr.toUpperCase() : sAddr.substring(0, delim).toUpperCase(); + } + } + } + } + } + } catch (Exception ex) { } // for now eat exceptions + return ""; + } + + /** + * parse binary file output + * @param output + * @return double + */ + protected static double parseBinOutput(String output) { + String[] toks = output.trim().split(":"); + if (toks.length == 2) { + return Double.parseDouble(toks[1]); + } + return -1; + } + /** * get the number of cores of device * @return int > 0 @@ -84,15 +167,18 @@ public class Utilities { protected static int getMyPID(String inName, boolean flag) { String commd; if (flag) - commd = "su -c busybox ps | grep " + inName + " | grep -v grep | head -1 | awk '{print $1}'"; + commd = "su -c busybox ps | grep " + + inName + " | grep -v grep | head -1 | awk '{print $1}'"; else - commd = "su -c busybox ps | grep " + inName + " | grep -v grep | head -1 | awk '{print $3}'"; + commd = "su -c busybox ps | grep " + + inName + " | grep -v grep | head -1 | awk '{print $3}'"; try { Process proc = Runtime.getRuntime().exec(commd); proc.waitFor(); String line; StringBuilder out = new StringBuilder(); - BufferedReader is = new BufferedReader(new InputStreamReader(proc.getInputStream())); + BufferedReader is = new BufferedReader( + new InputStreamReader(proc.getInputStream())); while ((line = is.readLine()) != null) { out.append(line).append("\n"); } @@ -120,6 +206,27 @@ public class Utilities { return false; } + /** + * check if a directory exists + * @param myDirectory + * @param createIfNot: try to create the folder if directory does not exist + * @return true/false + */ + protected static boolean dirExist(String myDirectory, boolean createIfNot) { + File file = new File(myDirectory); + if (file.exists() && file.isDirectory()) + return true; + if (createIfNot) { + try{ + file.mkdirs(); + } catch (Exception e) { + return false; + } + return true; + } + return false; + } + /** * parse CPU for a folder * @param folderName @@ -127,8 +234,9 @@ public class Utilities { */ protected static boolean parseCPUforFolder(String folderName) { try { - Process proc = Runtime.getRuntime().exec("su && cd " + MainActivity.outFolderPath + "/" + folderName - + " && ls *.cpuRaw"); + Process proc = Runtime.getRuntime().exec( + "su && cd " + MainActivity.outFolderPath + "/" + + folderName + " && ls *.cpuRaw"); proc.waitFor(); InputStream stdout = proc.getInputStream(); byte[] buffer = new byte[20]; @@ -150,9 +258,14 @@ public class Utilities { for (int i = 0; i < cpuFiles.length; ++i) { try { BufferedReader br = new BufferedReader( - new FileReader(MainActivity.outFolderPath + "/" + folderName + "/" + cpuFiles[i])); + new FileReader( + MainActivity.outFolderPath + "/" + + folderName + "/" + cpuFiles[i])); FileOutputStream os_cpu = new FileOutputStream( - new File(MainActivity.outFolderPath + "/" + folderName, cpuFiles[i].replace("cpuRaw", "cpu"))); + new File( + MainActivity.outFolderPath + "/" + + folderName, + cpuFiles[i].replace("cpuRaw", "cpu"))); String line; while ((line = br.readLine()) != null) { String[] toks = line.split("\\s+"); @@ -221,24 +334,24 @@ public class Utilities { protected static int findCorrespondingThrpt(int myI) { if (myI == 0) { - return 50000; + return 8 * 50000; } else if (myI == 1) { - return 100000; + return 8 * 100000; } else if (myI < 6) { - return 250000 * (myI - 1); + return 8 * 250000 * (myI - 1); } else if (myI < 24) { - return 1500000 + 500000 * (myI - 6); + return 8 * (1500000 + 500000 * (myI - 6)); } else if (myI > 24 && myI < 43) { - return 15000000 + 5000000 * (myI - 25); + return 8 * (15000000 + 5000000 * (myI - 25)); } else if (myI == 43) { - return 11000000; + return 8 * 11000000; } else if (myI == 44){ - return 13000000; + return 8 * 13000000; } else { // default unlimited if (MainActivity.isLocal) - return 100000000; + return 8 * 100000000; // for loopback, the unlimited shouldn't be really unlimited.. else - return 20000000; + return -1; } } diff --git a/OffloadingDemo/mobile/src/main/res/layout/activity_main.xml b/OffloadingDemo/mobile/src/main/res/layout/activity_main.xml index d5ae818..21c83df 100755 --- a/OffloadingDemo/mobile/src/main/res/layout/activity_main.xml +++ b/OffloadingDemo/mobile/src/main/res/layout/activity_main.xml @@ -40,70 +40,75 @@ - + + + + + -