diff --git a/app/build.gradle b/app/build.gradle
index c67a9ce0..c78cb18a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -81,6 +81,7 @@ android {
signingConfig signingConfigs.debug
}
}
+
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
@@ -99,6 +100,8 @@ android {
lint {
abortOnError false
}
+
+
}
spdxSbom {
@@ -122,6 +125,7 @@ spdxSbom {
dependencies {
implementation 'androidx.preference:preference:1.2.1'
implementation 'androidx.work:work-runtime:2.9.0'
+ implementation 'com.google.android.material:material:1.12.0'
def room_version = "2.6.1"
implementation "androidx.room:room-runtime:$room_version"
@@ -129,10 +133,9 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'com.google.guava:guava:33.2.1-jre'
implementation 'androidx.concurrent:concurrent-futures:1.2.0'
- implementation 'androidx.activity:activity:1.9.0'
- implementation 'androidx.fragment:fragment:1.8.1'
+ implementation 'androidx.activity:activity:1.9.1'
+ implementation 'androidx.fragment:fragment:1.8.2'
implementation 'androidx.appcompat:appcompat:1.7.0'
- implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.navigation:navigation-fragment:2.7.7'
implementation 'androidx.navigation:navigation-ui:2.7.7'
diff --git a/app/schemas/de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3ResultsDataBase/3.json b/app/schemas/de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3ResultsDataBase/3.json
index 59a986b4..92b88f80 100644
--- a/app/schemas/de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3ResultsDataBase/3.json
+++ b/app/schemas/de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3ResultsDataBase/3.json
@@ -2,11 +2,11 @@
"formatVersion": 1,
"database": {
"version": 3,
- "identityHash": "3d98e37212367d9d5ef195be31a59c58",
+ "identityHash": "12fc36c505cf323268351cd8ce794593",
"entities": [
{
"tableName": "iperf3_result_database",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` TEXT NOT NULL, `result` INTEGER NOT NULL, `uploaded` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `input` TEXT, PRIMARY KEY(`uid`))",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` TEXT NOT NULL, `result` INTEGER NOT NULL, `uploaded` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `input` TEXT, `intervals` TEXT, PRIMARY KEY(`uid`))",
"fields": [
{
"fieldPath": "uid",
@@ -37,13 +37,19 @@
"columnName": "input",
"affinity": "TEXT",
"notNull": false
+ },
+ {
+ "fieldPath": "intervals",
+ "columnName": "intervals",
+ "affinity": "TEXT",
+ "notNull": false
}
],
"primaryKey": {
+ "autoGenerate": false,
"columnNames": [
"uid"
- ],
- "autoGenerate": false
+ ]
},
"indices": [],
"foreignKeys": []
@@ -52,7 +58,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
- "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3d98e37212367d9d5ef195be31a59c58')"
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '12fc36c505cf323268351cd8ce794593')"
]
}
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6a7f0749..861218a2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -63,14 +63,21 @@
-
-
+
+
+
+
+
+
fromString(String value) {
+ Type listType = new TypeToken>() {}.getType();
+ return new Gson().fromJson(value, listType);
+ }
+
+ @TypeConverter
+ public static String fromArrayList(ArrayList list) {
+ Gson gson = new Gson();
+ return gson.toJson(list);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3InputConverter.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/Converter/Iperf3InputConverter.java
similarity index 61%
rename from app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3InputConverter.java
rename to app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/Converter/Iperf3InputConverter.java
index 61c014c5..979f4b8f 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3InputConverter.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/Converter/Iperf3InputConverter.java
@@ -6,22 +6,24 @@
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
-package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Converter;
import androidx.room.ProvidedTypeConverter;
import androidx.room.TypeConverter;
import com.google.gson.Gson;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3Input;
+
@ProvidedTypeConverter
public class Iperf3InputConverter {
@TypeConverter
- public Iperf3Fragment.Iperf3Input StringToIperf3Input(String string) {
- return new Gson().fromJson(string, Iperf3Fragment.Iperf3Input.class);
+ public Iperf3Input StringToIperf3Input(String string) {
+ return new Gson().fromJson(string, Iperf3Input.class);
}
@TypeConverter
- public String Iperf3InputToString(Iperf3Fragment.Iperf3Input example) {
+ public String Iperf3InputToString(Iperf3Input example) {
return new Gson().toJson(example);
}
}
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/Iperf3ResultsDataBase.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/Iperf3ResultsDataBase.java
new file mode 100644
index 00000000..3916d063
--- /dev/null
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/Iperf3ResultsDataBase.java
@@ -0,0 +1,32 @@
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database;
+
+import android.content.Context;
+import androidx.room.Database;
+import androidx.room.Room;
+import androidx.room.RoomDatabase;
+import androidx.room.TypeConverters;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Converter.IntervalsConverter;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Converter.Iperf3InputConverter;
+
+@Database(entities = {Iperf3RunResult.class}, version = 1, exportSchema = false)
+@TypeConverters({IntervalsConverter.class})
+public abstract class Iperf3ResultsDataBase extends RoomDatabase {
+ private static volatile Iperf3ResultsDataBase INSTANCE;
+
+ public abstract Iperf3RunResultDao iperf3RunResultDao();
+
+ public static Iperf3ResultsDataBase getDatabase(final Context context) {
+ if (INSTANCE == null) {
+ synchronized (Iperf3ResultsDataBase.class) {
+ if (INSTANCE == null) {
+ INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
+ Iperf3ResultsDataBase.class, "iperf3_database")
+ .addTypeConverter(new Iperf3InputConverter())
+ .allowMainThreadQueries()
+ .build();
+ }
+ }
+ }
+ return INSTANCE;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3RunResult.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/Iperf3RunResult.java
similarity index 65%
rename from app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3RunResult.java
rename to app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/Iperf3RunResult.java
index 1a7f9854..94113a12 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3RunResult.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/Iperf3RunResult.java
@@ -6,7 +6,7 @@
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
-package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
@@ -15,6 +15,12 @@
import androidx.room.TypeConverters;
import java.sql.Timestamp;
+import java.util.ArrayList;
+
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Converter.IntervalsConverter;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Converter.Iperf3InputConverter;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3Input;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Interval;
@Entity(tableName = "iperf3_result_database")
public class Iperf3RunResult {
@@ -33,9 +39,13 @@ public class Iperf3RunResult {
@ColumnInfo(name = "input")
@TypeConverters({Iperf3InputConverter.class})
- public Iperf3Fragment.Iperf3Input input;
+ public Iperf3Input input;
+
+ @ColumnInfo(name = "intervals")
+ @TypeConverters({IntervalsConverter.class})
+ public ArrayList intervals;
- public Iperf3RunResult(String uid, int result, boolean upload, Iperf3Fragment.Iperf3Input input,
+ public Iperf3RunResult(String uid, int result, boolean upload, Iperf3Input input,
Timestamp timestamp) {
this.uid = uid;
this.result = result;
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3RunResultDao.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/Iperf3RunResultDao.java
similarity index 66%
rename from app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3RunResultDao.java
rename to app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/Iperf3RunResultDao.java
index 158823aa..0295ba74 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3RunResultDao.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Database/Iperf3RunResultDao.java
@@ -6,7 +6,7 @@
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
-package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
@@ -14,10 +14,16 @@
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
+import androidx.room.TypeConverters;
import androidx.room.Update;
+import java.util.ArrayList;
import java.util.List;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Converter.IntervalsConverter;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Intervals;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Interval;
+
@Dao
public interface Iperf3RunResultDao {
@Query("SELECT * FROM iperf3_result_database")
@@ -44,6 +50,15 @@ public interface Iperf3RunResultDao {
@Query("UPDATE iperf3_result_database SET uploaded=:uploaded WHERE uid=:uid")
void updateUpload(String uid, boolean uploaded);
+ @Query("SELECT intervals FROM iperf3_result_database WHERE uid=:uid")
+ LiveData getIntervals(String uid);
+
+ @Query("UPDATE iperf3_result_database SET intervals=:intervals WHERE uid=:uid")
+ void updateIntervals(String uid, ArrayList intervals);
+
+ @Query("SELECT * FROM iperf3_result_database WHERE uid=:uid")
+ LiveData getLiveRunResult(String uid);
+
@Update
void update(Iperf3RunResult iperf3RunResult);
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Input/Iperf3CardAdapter.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Input/Iperf3CardAdapter.java
new file mode 100644
index 00000000..e2ee1d07
--- /dev/null
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Input/Iperf3CardAdapter.java
@@ -0,0 +1,48 @@
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Fragments.Input;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.viewpager2.adapter.FragmentStateAdapter;
+
+import java.util.ArrayList;
+
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Fragments.Iperf3Fragment;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Fragments.Output.Iperf3ListFragment;
+
+public class Iperf3CardAdapter extends FragmentStateAdapter {
+
+
+ private ArrayList fragmentList = new ArrayList<>();
+
+ public Iperf3CardAdapter(@NonNull FragmentActivity fragmentActivity) {
+ super(fragmentActivity);
+
+ this.addFragment(Iperf3CardFragment.newInstance(0));
+ this.fragmentList.add(Iperf3ListFragment.newInstance());
+ }
+
+ public void addFragment(Iperf3CardFragment fragment) {
+ int fragmentPosition = Math.max(fragmentList.size() - 1, 0);
+ fragmentList.add(fragmentPosition, fragment);
+ notifyItemInserted(fragmentList.size() - 2);
+ }
+
+ public ArrayList getFragments() {
+ ArrayList fragments = new ArrayList<>();
+ for (Fragment fragment : fragmentList) {
+ if(fragment instanceof Iperf3CardFragment) fragments.add((Iperf3CardFragment) fragment);
+ }
+ return fragments;
+ }
+ @NonNull
+ @Override
+ public Fragment createFragment(int position) {
+ return fragmentList.get(position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return fragmentList.size();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Input/Iperf3CardFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Input/Iperf3CardFragment.java
new file mode 100644
index 00000000..48163a4f
--- /dev/null
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Input/Iperf3CardFragment.java
@@ -0,0 +1,342 @@
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Fragments.Input;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ProgressBar;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+import com.google.android.material.button.MaterialButton;
+import com.google.android.material.button.MaterialButtonToggleGroup;
+import com.google.android.material.textfield.TextInputEditText;
+import com.google.android.material.textview.MaterialTextView;
+
+
+import java.sql.Timestamp;
+import java.util.UUID;
+import java.util.function.Consumer;
+
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3Input;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3Service;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SPType;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesGrouper;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R;
+
+public class Iperf3CardFragment extends Fragment {
+
+ private static final String ARG_POSITION = "position";
+ private ProgressBar progressBar;
+ private Iperf3Input iperf3Input;
+ private Context ct;
+ private MaterialButton sendBtn;
+ private View view;
+ //todo start iperf3 as a service
+ private TextInputEditText ip;
+ private TextInputEditText port;
+ private TextInputEditText bandwidth;
+ private TextInputEditText duration;
+ private TextInputEditText interval;
+ private TextInputEditText bytes;
+ private TextInputEditText streams;
+ private TextInputEditText cport;
+
+
+ private MaterialButtonToggleGroup mode;
+ private MaterialButtonToggleGroup protocol;
+ private MaterialButtonToggleGroup direction;
+
+ private MaterialButton modeClient;
+ private MaterialButton modeServer;
+ private MaterialButton protocolTCP;
+ private MaterialButton protocolUDP;
+ private MaterialButton directionUp;
+ private MaterialButton directionDown;
+ private MaterialButton directonBidir;
+
+ private SharedPreferencesGrouper spg;
+ private String TAG = "Iperf3CardFragment";
+
+
+ public static Iperf3CardFragment newInstance(int position) {
+ Iperf3CardFragment fragment = new Iperf3CardFragment();
+ Bundle args = new Bundle();
+ args.putInt(ARG_POSITION, position);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ this.ct = requireContext();
+ }
+
+ /**
+ * Create a text watcher
+ * @param consumer
+ * @param name
+ * @return
+ */
+ private TextWatcher createTextWatcher(Consumer consumer, String name) {
+ return new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+ consumer.accept(charSequence.toString());
+ spg.getSharedPreference(SPType.iperf3_sp).edit().putString(name, charSequence.toString()).apply();
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+ }
+ };
+ }
+
+ /**
+ * Set up the text watchers
+ */
+ private void setupTextWatchers() {
+ ip.addTextChangedListener(createTextWatcher(iperf3Input::setIp, Iperf3Input.IPERF3IP));
+ port.addTextChangedListener(createTextWatcher(iperf3Input::setPort, Iperf3Input.IPERF3PORT));
+ bandwidth.addTextChangedListener(createTextWatcher(iperf3Input::setBandwidth, Iperf3Input.IPERF3BANDWIDTH));
+ duration.addTextChangedListener(createTextWatcher(iperf3Input::setDuration, Iperf3Input.IPERF3DURATION));
+ interval.addTextChangedListener(createTextWatcher(iperf3Input::setInterval, Iperf3Input.IPERF3INTERVAL));
+ bytes.addTextChangedListener(createTextWatcher(iperf3Input::setBytes, Iperf3Input.IPERF3BYTES));
+ streams.addTextChangedListener(createTextWatcher(iperf3Input::setStreams, Iperf3Input.IPERF3STREAMS));
+ cport.addTextChangedListener(createTextWatcher(iperf3Input::setCport, Iperf3Input.IPERF3CPORT));
+ }
+
+ /**
+ * Set the text from the shared preferences
+ * @param editText
+ * @param key
+ */
+ private void setTextFromSharedPreferences(TextInputEditText editText, String key) {
+ if (spg.getSharedPreference(SPType.iperf3_sp).contains(key)) {
+ editText.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(key, ""));
+ }
+ }
+
+ /**
+ * Set the texts from the shared preferences
+ */
+ private void setTextsFromSharedPreferences(){
+ setTextFromSharedPreferences(ip, Iperf3Input.IPERF3IP);
+ setTextFromSharedPreferences(port, Iperf3Input.IPERF3PORT);
+ setTextFromSharedPreferences(bandwidth, Iperf3Input.IPERF3BANDWIDTH);
+ setTextFromSharedPreferences(duration, Iperf3Input.IPERF3DURATION);
+ setTextFromSharedPreferences(interval, Iperf3Input.IPERF3INTERVAL);
+ setTextFromSharedPreferences(bytes, Iperf3Input.IPERF3BYTES);
+ setTextFromSharedPreferences(streams, Iperf3Input.IPERF3STREAMS);
+ setTextFromSharedPreferences(cport, Iperf3Input.IPERF3CPORT);
+ }
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ view = inflater.inflate(R.layout.fragment_iperf3_card, container, false);
+ // Initialize the TextView
+ progressBar = view.findViewById(R.id.iperf3_progress);
+ progressBar.setVisibility(View.INVISIBLE);
+ iperf3Input = new Iperf3Input();
+ sendBtn = view.findViewById(R.id.iperf3_send);
+ spg = SharedPreferencesGrouper.getInstance(ct);
+ sendBtn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intent = new Intent(ct, Iperf3Service.class);
+ if(!iperf3Input.isValid()){
+ Toast.makeText(ct, "Please give at least an IP!", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ iperf3Input.setUuid(UUID.randomUUID().toString());
+ iperf3Input.setTimestamp(new Timestamp(System.currentTimeMillis()));
+ intent.putExtra("input", iperf3Input);
+
+ ct.startService(intent);
+
+ }
+ });
+
+
+ ip = view.findViewById(R.id.iperf3_ip);
+ port = view.findViewById(R.id.iperf3_port);
+ bandwidth = view.findViewById(R.id.iperf3_bandwidth);
+ duration = view.findViewById(R.id.iperf3_duration);
+ interval = view.findViewById(R.id.iperf3_interval);
+ bytes = view.findViewById(R.id.iperf3_bytes);
+ streams = view.findViewById(R.id.iperf3_streams);
+ cport = view.findViewById(R.id.iperf3_cport);
+
+
+ mode = view.findViewById(R.id.iperf3_mode_toggle_group);
+ protocol = view.findViewById(R.id.iperf3_protocol_toggle_group);
+ direction = view.findViewById(R.id.iperf3_direction_toggle_group);
+
+ modeClient = view.findViewById(R.id.iperf3_client_button);
+ modeServer = view.findViewById(R.id.iperf3_server_button);
+
+ protocolTCP = view.findViewById(R.id.iperf3_tcp_button);
+ protocolUDP = view.findViewById(R.id.iperf3_udp_button);
+
+ directionDown = view.findViewById(R.id.iperf3_download_button);
+ directionUp = view.findViewById(R.id.iperf3_upload_button);
+ directonBidir = view.findViewById(R.id.iperf3_bidir_button);
+
+ setupTextWatchers();
+ setTextsFromSharedPreferences();
+
+ try {
+ switch (Iperf3Input.Iperf3Mode.valueOf(spg.getSharedPreference(SPType.iperf3_sp).getString(Iperf3Input.IPERF3MODE, ""))){
+ case CLIENT:
+ updateModeState(modeClient, modeServer, Iperf3Input.Iperf3Mode.CLIENT);
+ break;
+ case SERVER:
+ updateModeState(modeServer, modeClient, Iperf3Input.Iperf3Mode.SERVER);
+ break;
+ case UNDEFINED:
+ default:
+ modeClient.setBackgroundColor(Color.TRANSPARENT);
+ modeServer.setBackgroundColor(Color.TRANSPARENT);
+ spg.getSharedPreference(SPType.iperf3_sp).edit().putString(Iperf3Input.IPERF3MODE, Iperf3Input.Iperf3Mode.UNDEFINED.toString()).apply();
+ break;
+ }
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "onCreateView: ", e);
+ }
+ try {
+ switch (Iperf3Input.Iperf3Protocol.valueOf(spg.getSharedPreference(SPType.iperf3_sp).getString(Iperf3Input.IPERF3PROTOCOL, ""))){
+ case TCP:
+ updateProtocolState(protocolTCP, protocolUDP, Iperf3Input.Iperf3Protocol.TCP);
+ break;
+ case UDP:
+ updateProtocolState(protocolUDP, protocolTCP, Iperf3Input.Iperf3Protocol.UDP);
+ break;
+ case UNDEFINED:
+ default:
+ protocolTCP.setBackgroundColor(Color.TRANSPARENT);
+ protocolUDP.setBackgroundColor(Color.TRANSPARENT);
+ spg.getSharedPreference(SPType.iperf3_sp).edit().putString(Iperf3Input.IPERF3PROTOCOL, Iperf3Input.Iperf3Protocol.UNDEFINED.toString()).apply();
+ break;
+ }
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "onCreateView: ", e);
+ }
+ try {
+ switch (Iperf3Input.Iperf3Direction.valueOf(spg.getSharedPreference(SPType.iperf3_sp).getString(Iperf3Input.IPERF3DIRECTION, ""))) {
+ case UP:
+ updateDirectionState(directionUp, directionDown, directonBidir, Iperf3Input.Iperf3Direction.UP);
+ break;
+ case DOWN:
+ updateDirectionState(directionDown, directionUp, directonBidir, Iperf3Input.Iperf3Direction.DOWN);
+ break;
+ case BIDIR:
+ updateDirectionState(directonBidir, directionUp, directionDown, Iperf3Input.Iperf3Direction.BIDIR);
+ break;
+ case UNDEFINED:
+ default:
+ directionUp.setBackgroundColor(Color.TRANSPARENT);
+ directionDown.setBackgroundColor(Color.TRANSPARENT);
+ directonBidir.setBackgroundColor(Color.TRANSPARENT);
+ break;
+ }
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "onCreateView: ", e);
+ }
+
+ mode.addOnButtonCheckedListener(new MaterialButtonToggleGroup.OnButtonCheckedListener() {
+ @Override
+ public void onButtonChecked(MaterialButtonToggleGroup group, int checkedId, boolean isChecked) {
+ if (isChecked) {
+ switch (checkedId) {
+ case R.id.iperf3_client_button:
+ updateModeState(modeClient, modeServer, Iperf3Input.Iperf3Mode.CLIENT);
+ break;
+ case R.id.iperf3_server_button:
+ updateModeState(modeServer, modeClient, Iperf3Input.Iperf3Mode.SERVER);
+ break;
+ }
+ }
+ }
+ });
+ protocol.addOnButtonCheckedListener(new MaterialButtonToggleGroup.OnButtonCheckedListener() {
+ @Override
+ public void onButtonChecked(MaterialButtonToggleGroup group, int checkedId, boolean isChecked) {
+ if (isChecked) {
+ switch (checkedId) {
+ case R.id.iperf3_tcp_button:
+ updateProtocolState(protocolTCP, protocolUDP, Iperf3Input.Iperf3Protocol.TCP);
+ break;
+ case R.id.iperf3_udp_button:
+ updateProtocolState(protocolUDP, protocolTCP, Iperf3Input.Iperf3Protocol.UDP);
+ break;
+ }
+ }
+ }
+ });
+ direction.addOnButtonCheckedListener(new MaterialButtonToggleGroup.OnButtonCheckedListener() {
+ @Override
+ public void onButtonChecked(MaterialButtonToggleGroup group, int checkedId, boolean isChecked) {
+ if (isChecked) {
+ switch (checkedId) {
+ case R.id.iperf3_upload_button:
+ updateDirectionState(directionUp, directionDown, directonBidir, Iperf3Input.Iperf3Direction.UP);
+ break;
+ case R.id.iperf3_download_button:
+ updateDirectionState(directionDown, directionUp, directonBidir, Iperf3Input.Iperf3Direction.DOWN);
+ break;
+ case R.id.iperf3_bidir_button:
+ updateDirectionState(directonBidir, directionUp, directionDown, Iperf3Input.Iperf3Direction.BIDIR);
+ break;
+ }
+ }
+ }
+ });
+
+ return view;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ view.requestLayout();
+ }
+
+
+
+ private void updateModeState(MaterialButton activeButton, MaterialButton inactiveButton, Iperf3Input.Iperf3Mode protocol) {
+ activeButton.setBackgroundColor(getResources().getColor(R.color.purple_500, null));
+ inactiveButton.setBackgroundColor(Color.TRANSPARENT);
+ iperf3Input.setMode(protocol);
+ spg.getSharedPreference(SPType.iperf3_sp).edit().putString(Iperf3Input.IPERF3MODE, protocol.toString()).apply();
+ }
+
+ private void updateProtocolState(MaterialButton activeButton, MaterialButton inactiveButton, Iperf3Input.Iperf3Protocol protocol) {
+ activeButton.setBackgroundColor(getResources().getColor(R.color.purple_500, null));
+ inactiveButton.setBackgroundColor(Color.TRANSPARENT);
+ iperf3Input.setProtocol(protocol);
+ spg.getSharedPreference(SPType.iperf3_sp).edit().putString(Iperf3Input.IPERF3PROTOCOL, protocol.toString()).apply();
+ }
+
+ private void updateDirectionState(MaterialButton activeButton, MaterialButton inactiveButton1, MaterialButton inactiveButton2, Iperf3Input.Iperf3Direction direction) {
+ activeButton.setBackgroundColor(getResources().getColor(R.color.purple_500, null));
+ inactiveButton1.setBackgroundColor(Color.TRANSPARENT);
+ inactiveButton2.setBackgroundColor(Color.TRANSPARENT);
+ iperf3Input.setDirection(direction);
+ spg.getSharedPreference(SPType.iperf3_sp).edit().putString(Iperf3Input.IPERF3DIRECTION, direction.toString()).apply();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Iperf3Fragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Iperf3Fragment.java
new file mode 100644
index 00000000..74eba88e
--- /dev/null
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Iperf3Fragment.java
@@ -0,0 +1,55 @@
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Fragments;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.viewpager2.widget.ViewPager2;
+
+import com.google.android.material.button.MaterialButton;
+
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Fragments.Input.Iperf3CardAdapter;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Fragments.Input.Iperf3CardFragment;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R;
+
+public class Iperf3Fragment extends Fragment{
+ private static final String TAG = "iperf3InputFragment";
+
+ private View v;
+ private Context ct;
+ private MaterialButton sendBtn;
+ private ViewPager2 viewPager;
+ private Iperf3CardAdapter adapter;
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup parent, @Nullable Bundle savedInstanceState) {
+ ct = requireContext();
+ v = inflater.inflate(R.layout.fragment_iperf3_input, parent, false);
+ viewPager = v.findViewById(R.id.iperf3_viewpager);
+ //linearLayout = v.findViewById(R.id.iperf3_plan);
+ adapter = new Iperf3CardAdapter(getActivity());
+
+ viewPager.setAdapter(adapter);
+
+ viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
+ @Override
+ public void onPageSelected(int position) {
+ super.onPageSelected(position);
+ adapter.notifyDataSetChanged();
+ v.requestLayout();
+ }
+ });
+
+
+ return v;
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3ListFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Output/Iperf3ListFragment.java
similarity index 68%
rename from app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3ListFragment.java
rename to app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Output/Iperf3ListFragment.java
index 6ae30a5d..2c5ce49a 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3ListFragment.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Output/Iperf3ListFragment.java
@@ -8,9 +8,10 @@
//from https://codeburst.io/android-swipe-menu-with-recyclerview-8f28a235ff28
-package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Fragments.Output;
import android.annotation.SuppressLint;
+import android.content.Context;
import android.graphics.Canvas;
import android.os.Bundle;
import android.os.Handler;
@@ -21,6 +22,7 @@
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
+import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -31,7 +33,13 @@
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
+import java.util.List;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3RecyclerViewAdapter;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3ResultsDataBase;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3RunResult;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3RunResultDao;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Worker.Iperf3ToLineProtocolWorker;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.SwipeController;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.SwipeControllerActions;
@@ -45,6 +53,30 @@ public class Iperf3ListFragment extends Fragment {
private LinearLayoutManager linearLayoutManager;
private FloatingActionButton uploadBtn;
private Iperf3ResultsDataBase db;
+ private Context context;
+
+
+
+ public static Iperf3ListFragment newInstance() {
+ Iperf3ListFragment fragment = new Iperf3ListFragment();
+ Bundle args = new Bundle();
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+
+
+ private void observeDatabaseChanges() {
+ if(db == null) return;
+ db.iperf3RunResultDao().getAll().observe(getViewLifecycleOwner(), new Observer>() {
+ @Override
+ public void onChanged(@Nullable List runResults) {
+ updateIperf3ListAdapter();
+ }
+ });
+ }
+
+
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -52,53 +84,57 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
@SuppressLint("NotifyDataSetChanged")
public void updateIperf3ListAdapter() {
- if (this.adapter != null) {
- this.adapter.notifyDataSetChanged();
- }
+ if (this.adapter != null) this.adapter.notifyDataSetChanged();
}
@SuppressLint("ClickableViewAccessibility")
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_iperf3_list, parent, false);
- ArrayList uids = this.getArguments().getStringArrayList("iperf3List");
+ this.context = requireContext();
+
recyclerView = v.findViewById(R.id.runners_list);
uploadBtn = v.findViewById(R.id.iperf3_upload_button);
+ db = Iperf3ResultsDataBase.getDatabase(this.context);
+
+ observeDatabaseChanges();
+
+
linearLayoutManager =
new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
+ this.adapter = new Iperf3RecyclerViewAdapter(getActivity(),
+ new ArrayList(db.iperf3RunResultDao().getIDs()),
+ uploadBtn);
+
+
recyclerView.setLayoutManager(linearLayoutManager);
- adapter = new Iperf3RecyclerViewAdapter(getActivity(), uids, uploadBtn);
recyclerView.setAdapter(adapter);
- db = Iperf3ResultsDataBase.getDatabase(requireContext());
-
swipeController = new SwipeController(new SwipeControllerActions() {
@SuppressLint("NotifyDataSetChanged")
@Override
public void onRightClicked(int position) {
WorkManager iperf3WM = WorkManager.getInstance(getContext());
- String uid = uids.get(position);
+ String uid = new ArrayList(db.iperf3RunResultDao().getIDs()).get(position);
iperf3WM.cancelAllWorkByTag(uid);
Iperf3RunResultDao iperf3RunResultDao = Iperf3ResultsDataBase.getDatabase(requireContext()).iperf3RunResultDao();
Iperf3RunResult runResult = iperf3RunResultDao.getRunResult(uid);
-
Data.Builder iperf3Data = new Data.Builder();
- iperf3Data.putString("rawIperf3file", runResult.input.iperf3rawIperf3file);
- iperf3Data.putString("iperf3LineProtocolFile", runResult.input.iperf3LineProtocolFile);
- iperf3Data.putString("measurementName", runResult.input.measurementName);
- iperf3Data.putString("ip", runResult.input.iperf3IP);
- iperf3Data.putString("port", runResult.input.iperf3Port);
- iperf3Data.putString("bandwidth", runResult.input.iperf3Bandwidth);
- iperf3Data.putString("duration", runResult.input.iperf3Duration);
- iperf3Data.putString("interval", runResult.input.iperf3Interval);
- iperf3Data.putString("bytes", runResult.input.iperf3Bytes);
- iperf3Data.putString("protocol", Iperf3Utils.getProtocolString(runResult.input.iperf3IdxProtocol));
- iperf3Data.putBoolean("rev", runResult.input.iperf3Reverse);
- iperf3Data.putBoolean("biDir", runResult.input.iperf3BiDir);
- iperf3Data.putBoolean("oneOff", runResult.input.iperf3OneOff);
- iperf3Data.putString("client", Iperf3Utils.getModeString(runResult.input.iperf3IdxMode));
- iperf3Data.putString("timestamp", runResult.input.timestamp.toString());
+ iperf3Data.putString("rawIperf3file", runResult.input.getRawFile());
+ iperf3Data.putString("iperf3LineProtocolFile", runResult.input.getLineProtocolFile());
+ iperf3Data.putString("measurementName", runResult.input.getMeasurementName());
+ iperf3Data.putString("ip", runResult.input.getIp());
+ iperf3Data.putString("port", runResult.input.getPort());
+ iperf3Data.putString("bandwidth", runResult.input.getBandwidth());
+ iperf3Data.putString("duration", runResult.input.getDuration());
+ iperf3Data.putString("interval", runResult.input.getInterval());
+ iperf3Data.putString("bytes", runResult.input.getBytes());
+ iperf3Data.putString("protocol", runResult.input.getProtocol().toString());
+ iperf3Data.putString("direction", runResult.input.getDirection().toString());
+ iperf3Data.putBoolean("oneOff", runResult.input.isOneOff());
+ iperf3Data.putString("mode", runResult.input.getMode().toString());
+ iperf3Data.putString("timestamp", runResult.input.getTimestamp().toString());
OneTimeWorkRequest iperf3LP =
new OneTimeWorkRequest
@@ -121,13 +157,12 @@ public void run() {
@Override
public void onLeftClicked(int position) {
Bundle input = new Bundle();
- input.putString("uid", uids.get(position));
+ input.putString("uid", new ArrayList(db.iperf3RunResultDao().getIDs()).get(position));
getActivity().getSupportFragmentManager().setFragmentResult("input", input);
getActivity().getSupportFragmentManager().popBackStack();
}
});
-
ItemTouchHelper itemTouchhelper = new ItemTouchHelper(swipeController);
itemTouchhelper.attachToRecyclerView(recyclerView);
@@ -137,6 +172,8 @@ public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
swipeController.onDraw(c);
}
});
+
+
return v;
}
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3LogFragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Output/Iperf3LogFragment.java
similarity index 68%
rename from app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3LogFragment.java
rename to app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Output/Iperf3LogFragment.java
index d6364041..d12a81c1 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3LogFragment.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Fragments/Output/Iperf3LogFragment.java
@@ -6,7 +6,7 @@
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
-package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Fragments.Output;
import android.content.Context;
import android.graphics.drawable.Drawable;
@@ -19,6 +19,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -29,15 +30,13 @@
import androidx.core.widget.TextViewCompat;
import androidx.fragment.app.Fragment;
-import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Error;
-import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Interval;
-import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Sum.SUM_TYPE;
-import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Sum.Sum;
-import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Sum.UDP.UDP_DL_SUM;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3Input;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3ResultsDataBase;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3RunResult;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3Utils;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Metric.METRIC_TYPE;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Metric.Metric;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
@@ -67,6 +66,7 @@ public class Iperf3LogFragment extends Fragment {
private Metric defaultRTT;
private Metric defaultJITTER;
private Metric PACKET_LOSS;
+ private Context context;
public Iperf3LogFragment() {
}
@@ -76,6 +76,7 @@ public Iperf3LogFragment() {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.db = Iperf3ResultsDataBase.getDatabase(getActivity().getApplicationContext());
+ this.context = requireContext();
}
private void setFields(Iperf3RunResult iperf3RunResult) {
@@ -97,13 +98,13 @@ public void run() {
try {
br = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
- iperf3OutputViewer.setText(String.format("no iPerf3 file found, with following path: \n %s", iperf3RunResult.input.iperf3rawIperf3file));
+ iperf3OutputViewer.setText(String.format("no iPerf3 file found, with following path: \n %s", iperf3RunResult.input.getRawFile()));
logHandler.removeCallbacks(logUpdate);
return;
}
String line;
-
- Iperf3Parser iperf3Parser = new Iperf3Parser(iperf3RunResult.input.iperf3rawIperf3file);
+ /*
+ Iperf3Parser iperf3Parser = new Iperf3Parser(iperf3RunResult.input.getRawFile());
iperf3Parser.addPropertyChangeListener(new PropertyChangeListener() {
private void parseSum(Sum sum, Metric throughput){
@@ -153,7 +154,7 @@ public void propertyChange(PropertyChangeEvent evt) {
}
});
- iperf3Parser.parse();
+ iperf3Parser.parse();*/
if (iperf3RunResult.result != -100) {
logHandler.removeCallbacks(logUpdate);
return;
@@ -164,8 +165,59 @@ public void propertyChange(PropertyChangeEvent evt) {
}
};
+ private TextView createTextView(Context ct, String text, float weight) {
+ TextView textView = new TextView(ct);
+ textView.setText(text);
+ LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT);
+ layoutParams.weight = weight;
+ textView.setLayoutParams(layoutParams);
+ return textView;
+ }
+ private LinearLayout getTextView(String name, String value) {
+ if(value == null) return null;
+ if(value.equals("")) return null;
+ LinearLayout mainLL = new LinearLayout(context);
+ mainLL.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+ mainLL.setOrientation(LinearLayout.HORIZONTAL);
+
+ TextView parameterName = createTextView(context, name, 0.25F);
+ TextView parameterValue = createTextView(context, value, 0.75F);
+
+ mainLL.addView(parameterName);
+ mainLL.addView(parameterValue);
+ return mainLL;
+ }
+
+ private void addTextView(LinearLayout ll, String name, String value) {
+ LinearLayout mainLL = getTextView(name, value);
+ if(mainLL != null) ll.addView(mainLL);
+ }
+
+ public LinearLayout getInputAsLinearLayoutKeyValue(Iperf3Input input) {
+ LinearLayout main = new LinearLayout(context);
+ main.setOrientation(LinearLayout.VERTICAL);
+ LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
+ 0,
+ FrameLayout.LayoutParams.WRAP_CONTENT);
+ layoutParams.weight = 8f;
+ main.setLayoutParams(layoutParams);
+
+ addTextView(main, Iperf3Input.IPERF3IP.replace("iperf3", ""), input.getIp());
+ addTextView(main, Iperf3Input.IPERF3PORT.replace("iperf3", ""), input.getPort());
+ addTextView(main, Iperf3Input.IPERF3PROTOCOL.replace("iperf3Idx", ""), input.getProtocol().toString());
+ addTextView(main, Iperf3Input.IPERF3MODE.replace("iperf3Idx", ""), input.getMode().toPrettyPrint());
+ addTextView(main, Iperf3Input.IPERF3DIRECTION.replace("iperf3", ""), input.getDirection().toPrettyPrint());
+ addTextView(main, Iperf3Input.IPERF3BANDWIDTH.replace("iperf3", ""), input.getBandwidth());
+ addTextView(main, Iperf3Input.IPERF3DURATION.replace("iperf3", ""), input.getDuration());
+ addTextView(main, Iperf3Input.IPERF3UUID.replace("iperf3", ""), input.getUuid());
+ addTextView(main, Iperf3Input.IPERF3STREAMS.replace("iperf3", ""), input.getStreams());
+ addTextView(main, Iperf3Input.IPERF3TIMESTAMP.replace("iperf3", ""), input.getTimestamp().toString());
+
+ return main;
+ }
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -186,8 +238,8 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
mainLL.setLayoutParams(layoutParams);
LinearLayout.LayoutParams foo = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT);
foo.setMargins(30, 10, 0, 0);
firstRow.setLayoutParams(foo);
@@ -215,26 +267,19 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
uploadIconView.setLayoutParams(uploadIconViewLayout);
- parameterLL = iperf3RunResult.input.getInputAsLinearLayoutKeyValue(new LinearLayout(ct), ct);
-
-
-
- firstRow.addView(parameterLL);
-
LinearLayout headerWrapper = new LinearLayout(ct);
LinearLayout.LayoutParams headerWrapperLayout = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT);
headerWrapper.setLayoutParams(headerWrapperLayout);
headerWrapper.setOrientation(LinearLayout.VERTICAL);
CardView cardView = new CardView(ct);
- LinearLayout.LayoutParams cardViewLayout = Iperf3Utils.getLayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT,
- 0);
+ CardView.LayoutParams cardViewLayout = new CardView.LayoutParams(
+ CardView.LayoutParams.MATCH_PARENT,
+ CardView.LayoutParams.WRAP_CONTENT);
headerWrapper.setPadding(30, 30, 30, 30);
cardView.setLayoutParams(cardViewLayout);
cardView.setRadius(10);
@@ -254,6 +299,9 @@ public void onClick(View v) {
header.setLayoutParams(headerLayout);
header.setOrientation(LinearLayout.HORIZONTAL);
+ firstRow.addView(getInputAsLinearLayoutKeyValue(iperf3RunResult.input));
+
+
TextView headerName = new TextView(ct);
headerName.setText("iPerf3 run");
LinearLayout.LayoutParams headerNameLayout = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -313,31 +361,44 @@ public void onClick(View v) {
metricLL.addView(defaultThroughput.createMainLL("Throughput"));
- if(iperf3RunResult.input.iperf3BiDir) {
- metricLL.addView(defaultReverseThroughput.createMainLL("Throughput"));
- if(iperf3RunResult.input.iperf3IdxProtocol == 0) {
- //defaultRTT = new Metric(METRIC_TYPE.RTT);
- //metricLL.addView(defaultRTT.createOneDirection("RTT"));
- }
- if(iperf3RunResult.input.iperf3IdxProtocol == 1) {
- defaultJITTER = new Metric(METRIC_TYPE.JITTER, ct);
- metricLL.addView(defaultJITTER.createMainLL("Jitter ms"));
- PACKET_LOSS = new Metric(METRIC_TYPE.PACKET_LOSS, ct);
- metricLL.addView(PACKET_LOSS.createMainLL("Packet Loss %"));
- }
- }
- if(iperf3RunResult.input.iperf3Reverse) {
- if(iperf3RunResult.input.iperf3IdxProtocol == 1) {
- defaultJITTER = new Metric(METRIC_TYPE.JITTER, ct);
- metricLL.addView(defaultJITTER.createMainLL("Jitter ms"));
- PACKET_LOSS = new Metric(METRIC_TYPE.JITTER, ct);
- metricLL.addView(PACKET_LOSS.createMainLL("Packet Loss %"));
- }
- } else if(!iperf3RunResult.input.iperf3BiDir) {
- if(iperf3RunResult.input.iperf3IdxProtocol == 0) {
- //defaultRTT = new Metric(METRIC_TYPE.RTT);
- //metricLL.addView(defaultRTT.createOneDirection("RTT ms"));
- }
+
+
+ switch (iperf3RunResult.input.getDirection()){
+ case UP:
+ defaultThroughput.getDirectionName().setText("Uplink Mbit/s");
+ //display RTT when available - https://github.com/esnet/iperf/issues/1724
+ break;
+ case DOWN:
+ defaultThroughput.getDirectionName().setText("Downlink Mbit/s");
+ switch (iperf3RunResult.input.getProtocol()){
+ case TCP:
+ break;
+ case UDP:
+ defaultJITTER = new Metric(METRIC_TYPE.JITTER, ct);
+ metricLL.addView(defaultJITTER.createMainLL("Jitter ms"));
+ PACKET_LOSS = new Metric(METRIC_TYPE.PACKET_LOSS, ct);
+ metricLL.addView(PACKET_LOSS.createMainLL("Packet Loss %"));
+ break;
+ }
+ break;
+ case BIDIR:
+ metricLL.addView(defaultReverseThroughput.createMainLL("Throughput"));
+ switch (iperf3RunResult.input.getProtocol()){
+ case TCP:
+ defaultThroughput.getDirectionName().setText("Downlink Mbit/s");
+ defaultReverseThroughput.getDirectionName().setText("Uplink Mbit/s");
+ break;
+ case UDP:
+ defaultThroughput.getDirectionName().setText("Downlink Mbit/s");
+ defaultReverseThroughput.getDirectionName().setText("Uplink Mbit/s");
+ defaultJITTER = new Metric(METRIC_TYPE.JITTER, ct);
+ metricLL.addView(defaultJITTER.createMainLL("Jitter ms"));
+ PACKET_LOSS = new Metric(METRIC_TYPE.PACKET_LOSS, ct);
+ metricLL.addView(PACKET_LOSS.createMainLL("Packet Loss %"));
+ break;
+ }
+
+ break;
}
mainLL.addView(metricLL);
@@ -346,11 +407,11 @@ public void onClick(View v) {
mainLL.addView(secondRow);
- if(iperf3RunResult.input.iperf3rawIperf3file == null){
+ if(iperf3RunResult.input.getRawFile() == null){
iperf3OutputViewer.setText("iPerf3 file path empty!");
return v;
}
- file = new File(iperf3RunResult.input.iperf3rawIperf3file);
+ file = new File(iperf3RunResult.input.getRawFile());
logHandler = new Handler(Looper.myLooper());
@@ -358,6 +419,12 @@ public void onClick(View v) {
return v;
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ v.requestLayout();
+ }
+
public void onPause() {
super.onPause();
if(logHandler != null) logHandler.removeCallbacks(logUpdate);
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Intervals.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Intervals.java
index 08635896..a2c18fd4 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Intervals.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Intervals.java
@@ -1,11 +1,17 @@
package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+import androidx.room.TypeConverters;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Interval;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Converter.IntervalsConverter;
import java.util.ArrayList;
public class Intervals {
- private final ArrayList intervals;
+ @TypeConverters({IntervalsConverter.class})
+ private ArrayList intervals;
+ public Intervals(ArrayList intervals){
+ this.intervals = intervals;
+ }
public Intervals(){
this.intervals = new ArrayList<>();
}
@@ -16,4 +22,7 @@ public ArrayList getIntervalArrayList(){
return intervals;
}
-}
+ public void setIntervals(ArrayList intervals){
+ this.intervals = intervals;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Executor.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Executor.java
new file mode 100644
index 00000000..db77b0fa
--- /dev/null
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Executor.java
@@ -0,0 +1,119 @@
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+
+import static android.app.PendingIntent.getActivity;
+
+import android.content.Context;
+import android.util.Log;
+
+import androidx.work.Data;
+import androidx.work.OneTimeWorkRequest;
+import androidx.work.WorkInfo;
+import androidx.work.WorkManager;
+
+import java.util.UUID;
+
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Worker.Iperf3ExecuterWorker;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Worker.Iperf3ToLineProtocolWorker;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Worker.Iperf3UploadWorker;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3ResultsDataBase;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3RunResult;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3RunResultDao;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SPType;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesGrouper;
+
+public class Iperf3Executor {
+ private static final String TAG = "Iperf3Executor";
+ private WorkManager workManager;
+ private Context context;
+ private Iperf3Input iperf3Input;
+ private Data.Builder dataBuilder;
+ private Iperf3RunResultDao iperf3RunResultDao;
+ private SharedPreferencesGrouper spg;
+ private OneTimeWorkRequest iperf3WR;
+ private OneTimeWorkRequest iperf3LP;
+ private OneTimeWorkRequest iperf3UP;
+
+
+ public Iperf3Executor(Context context, Iperf3Input iperf3Input) {
+ this.context = context;
+ spg = SharedPreferencesGrouper.getInstance(context);
+ workManager = WorkManager.getInstance(context);
+ iperf3RunResultDao = Iperf3ResultsDataBase.getDatabase(context).iperf3RunResultDao();
+ this.iperf3Input = iperf3Input;
+ this.dataBuilder = this.iperf3Input.getInputAsDataBuilder();
+
+
+ iperf3WR = new OneTimeWorkRequest
+ .Builder(Iperf3ExecuterWorker.class)
+ .setInputData(this.dataBuilder.build())
+ .addTag("iperf3Run")
+ .addTag(iperf3Input.getUuid())
+ .build();
+ iperf3LP = new OneTimeWorkRequest
+ .Builder(Iperf3ToLineProtocolWorker.class)
+ .setInputData(this.dataBuilder.build())
+ .build();
+ iperf3UP = new OneTimeWorkRequest
+ .Builder(Iperf3UploadWorker.class)
+ .setInputData(this.dataBuilder.build())
+ .addTag("iperf3")
+ .build();
+ iperf3RunResultDao.insert(new Iperf3RunResult(this.iperf3Input.getUuid(),
+ -100,
+ false,
+ this.iperf3Input,
+ this.iperf3Input.getTimestamp()));
+
+
+
+
+ workManager.getWorkInfoByIdLiveData(iperf3WR.getId()).observeForever(workInfo -> {
+ int iperf3_result;
+ iperf3_result = workInfo.getOutputData().getInt("iperf3_result", -100);
+ if (workInfo.getState().equals(WorkInfo.State.CANCELLED)) {
+ iperf3_result = -1;
+ }
+ iperf3RunResultDao.updateResult(this.iperf3Input.getUuid(), iperf3_result);
+ Log.d(TAG, "onChanged: iperf3_result: " + iperf3_result);
+ /*if (iperf3_result == -100) {
+ progressIndicator.setVisibility(LinearProgressIndicator.VISIBLE);
+ if (!isModeSpinnerClient()) {
+ progressbarHandler.postDelayed(progressbarUpdate, SHOW_PROGRESSBAR);
+ }
+ } else if (iperf3_result != 0) {
+ progressIndicator.setIndicatorColor(failedColors);
+ progressbarHandler.postDelayed(progressbarUpdate, SHOW_PROGRESSBAR);
+
+ } else {
+ progressIndicator.setIndicatorColor(succesColors);
+ progressbarHandler.postDelayed(progressbarUpdate, SHOW_PROGRESSBAR);
+ }*/
+ });
+
+ workManager.getWorkInfoByIdLiveData(iperf3UP.getId()).observeForever(workInfo -> {
+ boolean iperf3_upload;
+ iperf3_upload = workInfo.getOutputData().getBoolean("iperf3_upload", false);
+ Log.d(TAG, "onChanged: iperf3_upload: " + iperf3_upload);
+ iperf3RunResultDao.updateUpload(this.iperf3Input.getUuid(), iperf3_upload);
+ });
+
+ }
+
+ public UUID getUuid() {
+ return this.iperf3WR.getId();
+ }
+
+ public void start() {
+ if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false)) {
+ workManager.beginWith(iperf3WR).then(iperf3LP).then(iperf3UP).enqueue();
+ } else {
+ workManager.beginWith(iperf3WR).then(iperf3LP).enqueue();
+ }
+
+ }
+
+ public void stop(){
+ workManager.cancelAllWorkByTag(this.iperf3Input.getUuid());
+ }
+
+}
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Fragment.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Fragment.java
deleted file mode 100644
index ff16e37c..00000000
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Fragment.java
+++ /dev/null
@@ -1,857 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2023 Peter Hasse
- * SPDX-FileCopyrightText: 2023 Johann Hackler
- * SPDX-FileCopyrightText: 2023 Fraunhofer FOKUS
- *
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- */
-
-package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.Looper;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentResultListener;
-import androidx.lifecycle.MutableLiveData;
-import androidx.lifecycle.Observer;
-import androidx.navigation.NavController;
-import androidx.navigation.fragment.NavHostFragment;
-import androidx.work.Data;
-import androidx.work.OneTimeWorkRequest;
-import androidx.work.WorkInfo;
-import androidx.work.WorkManager;
-
-import com.google.android.material.progressindicator.LinearProgressIndicator;
-import com.google.common.util.concurrent.ListenableFuture;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.UUID;
-
-import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R;
-import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SPType;
-import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesGrouper;
-
-public class Iperf3Fragment extends Fragment {
- private static final String TAG = "iperf3InputFragment";
- private final int SHOW_PROGRESSBAR = 3000;
- private final String IPERF3IP = "iperf3IP";
- private final String IPERF3PORT = "iperf3Port";
- private final String IPERF3BANDWIDTH = "iperf3Bandwidth";
- private final String IPERF3DURATION = "iperf3Duration";
- private final String IPERF3INTERVAL = "iperf3Interval";
- private final String IPERF3BYTES = "iperf3Bytes";
- private final String IPERF3STREAMS = "iperf3Streams";
- private final String IPERF3BIDIR = "iperf3BiDir";
- private final String IPERF3REVERSE = "iperf3Reverse";
- private final String IPERF3JSON = "iperf3Json";
- private final String IPERF3ONEOFF = "iperf3OneOff";
- private final String IPERF3IDXPROTOCOL = "iperf3IdxProtocol";
- private final String IPERF3IDXMODE = "iperf3IdxMode";
- private final String IPERF3CPORT = "iperf3cport";
- private CheckBox iperf3BiDir;
- private CheckBox iperf3Reverse;
-
- private CheckBox iperf3OneOff;
- private EditText iperf3EtIp;
- private EditText iperf3EtPort;
- private EditText iperf3EtBandwidth;
- private EditText iperf3EtDuration;
- private EditText iperf3EtInterval;
- private EditText iperf3EtBytes;
- private EditText iperf3EtStreams;
- private EditText iperf3Cport;
- private Button sendBtn;
- private Button instancesBtn;
- private Spinner protocolSpinner;
- private Spinner iperf3ModeSpinner;
- private Iperf3RunResultDao iperf3RunResultDao;
- private LinearProgressIndicator progressIndicator;
- private int[] failedColors;
- private int[] runningColors;
- private int[] succesColors;
- private LinkedList editTexts;
- private String rawIperf3file;
- private String logFileDir;
- private String logFileName;
- private View v;
- private SharedPreferencesGrouper spg;
- private Iperf3Input input;
- private WorkManager iperf3WM;
- private Iperf3ResultsDataBase db;
- private ArrayList uids;
- private Context ct;
- private final Runnable progressbarUpdate = new Runnable() {
- @Override
- public void run() {
- progressIndicator.setVisibility(LinearProgressIndicator.INVISIBLE);
- progressIndicator.setIndicatorColor(runningColors);
- }
- };
-
- @Override
- public void onPause() {
- super.onPause();
- }
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- this.input = new Iperf3Input();
- this.db = Iperf3ResultsDataBase.getDatabase(getActivity().getApplicationContext());
- this.uids = new ArrayList<>(this.db.iperf3RunResultDao().getIDs());
- this.iperf3WM = WorkManager.getInstance(getActivity().getApplicationContext());
- this.logFileDir =
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
- .getAbsolutePath() + "/omnt/iperf3RawLogs/";
- this.iperf3RunResultDao = db.iperf3RunResultDao();
- File iperf3Path = new File(this.logFileDir);
- if (!iperf3Path.exists()) {
- iperf3Path.mkdir();
- }
- this.ct = requireContext();
- this.spg = SharedPreferencesGrouper.getInstance(this.ct);
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
-
- NavController navController = NavHostFragment.findNavController(this);
- MutableLiveData liveData = navController.getCurrentBackStackEntry()
- .getSavedStateHandle()
- .getLiveData("uid");
-
-
-
- liveData.observe(getViewLifecycleOwner(), new Observer() {
- @Override
- public void onChanged(String s) {
- Iperf3RunResult iperf3RunResult = db.iperf3RunResultDao().getRunResult(s);
-
- iperf3EtIp.setText(iperf3RunResult.input.iperf3IP);
- iperf3EtPort.setText(iperf3RunResult.input.iperf3Port);
- iperf3EtBandwidth.setText(iperf3RunResult.input.iperf3Bandwidth);
- iperf3EtDuration.setText(iperf3RunResult.input.iperf3Duration);
- iperf3EtInterval.setText(iperf3RunResult.input.iperf3Interval);
- iperf3EtBytes.setText(iperf3RunResult.input.iperf3Bytes);
- iperf3Cport.setText(iperf3RunResult.input.iperf3Cport);
-
- iperf3Reverse.setChecked(iperf3RunResult.input.iperf3Reverse);
- iperf3BiDir.setChecked(iperf3RunResult.input.iperf3BiDir);
- iperf3OneOff.setChecked(iperf3RunResult.input.iperf3OneOff);
- protocolSpinner.setSelection(iperf3RunResult.input.iperf3IdxProtocol);
- iperf3ModeSpinner.setSelection(iperf3RunResult.input.iperf3IdxMode);
-
-
- }
- });
- }
-
-
- private void saveTextInputToSharedPreferences(EditText field, String name) {
- field.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- spg.getSharedPreference(SPType.iperf3_sp).edit().putString(name, field.getText().toString()).apply();
- }
-
- @Override
- public void afterTextChanged(Editable editable) {
-
- }
- });
-
- }
-
-
-
- private void saveCheckboxInputToSharedPreferences(CheckBox box, String name) {
- box.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- spg.getSharedPreference(SPType.iperf3_sp).edit().putBoolean(name, box.isChecked()).apply();
- }
- });
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
- v = inflater.inflate(R.layout.fragment_iperf3_input, parent, false);
- iperf3EtIp = v.findViewById(R.id.iperf3_ip);
- iperf3EtPort = v.findViewById(R.id.iperf3_port);
- iperf3EtBandwidth = v.findViewById(R.id.iperf3_bandwidth);
- iperf3EtDuration = v.findViewById(R.id.iperf3_duration);
-
-
-
-
- iperf3EtInterval = v.findViewById(R.id.iperf3_interval);
- iperf3EtBytes = v.findViewById(R.id.iperf3_bytes);
- iperf3EtStreams = v.findViewById(R.id.iperf3_streams);
- iperf3Cport = v.findViewById(R.id.iperf3_cport);
- progressIndicator = v.findViewById(R.id.iperf3_progress);
-
- iperf3EtDuration.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- iperf3EtBytes.setEnabled(s.length() <= 0);
- }
-
- @Override
- public void afterTextChanged(Editable s) {
-
- }
- });
-
-
- iperf3EtBytes.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- iperf3EtDuration.setEnabled(s.length() <= 0);
- }
-
- @Override
- public void afterTextChanged(Editable s) {
-
- }
- });
-
- saveTextInputToSharedPreferences(iperf3EtIp, IPERF3IP);
- saveTextInputToSharedPreferences(iperf3EtPort, IPERF3PORT);
- saveTextInputToSharedPreferences(iperf3EtBandwidth, IPERF3BANDWIDTH);
- saveTextInputToSharedPreferences(iperf3EtDuration, IPERF3DURATION);
- saveTextInputToSharedPreferences(iperf3EtInterval, IPERF3INTERVAL);
- saveTextInputToSharedPreferences(iperf3EtBytes, IPERF3BYTES);
- saveTextInputToSharedPreferences(iperf3EtStreams, IPERF3STREAMS);
- saveTextInputToSharedPreferences(iperf3Cport, IPERF3CPORT);
-
- failedColors = new int[] {getContext().getColor(R.color.crimson),
- getContext().getColor(R.color.crimson), getContext().getColor(R.color.crimson)};
- runningColors = new int[] {getContext().getColor(R.color.purple_500),
- getContext().getColor(R.color.crimson), getContext().getColor(R.color.forestgreen)};
- succesColors = new int[] {getContext().getColor(R.color.forestgreen),
- getContext().getColor(R.color.forestgreen), getContext().getColor(R.color.forestgreen)};
-
- progressIndicator.setIndicatorColor(runningColors);
- progressIndicator.setIndeterminateAnimationType(
- LinearProgressIndicator.INDETERMINATE_ANIMATION_TYPE_CONTIGUOUS);
- progressIndicator.setVisibility(LinearProgressIndicator.INVISIBLE);
-
- editTexts = new LinkedList<>();
- editTexts.add(iperf3EtIp);
- editTexts.add(iperf3EtPort);
- editTexts.add(iperf3EtBandwidth);
- editTexts.add(iperf3EtDuration);
- editTexts.add(iperf3EtInterval);
- editTexts.add(iperf3EtBytes);
- editTexts.add(iperf3EtStreams);
- editTexts.add(iperf3Cport);
- sendBtn = v.findViewById(R.id.iperf3_send);
- instancesBtn = v.findViewById(R.id.iperf3_instances_button);
-
- sendBtn.setOnClickListener(this::executeIperfCommand);
- instancesBtn.setOnClickListener(this::showInstances);
-
- iperf3BiDir = v.findViewById(R.id.iperf_bidir);
- iperf3Reverse = v.findViewById(R.id.iperf3_reverse);
- iperf3OneOff = v.findViewById(R.id.iperf3_one_off);
-
- saveCheckboxInputToSharedPreferences(iperf3BiDir, IPERF3BIDIR);
- saveCheckboxInputToSharedPreferences(iperf3Reverse, IPERF3REVERSE);
- saveCheckboxInputToSharedPreferences(iperf3OneOff, IPERF3ONEOFF);
-
- protocolSpinner = v.findViewById(R.id.iperf3_protocol_spinner);
- ArrayAdapter adapter =
- ArrayAdapter.createFromResource(getContext(), R.array.iperf_protocol,
- R.layout.support_simple_spinner_dropdown_item);
- adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
- protocolSpinner.setAdapter(adapter);
-
- iperf3ModeSpinner = v.findViewById(R.id.iperf3_mode_spinner);
- ArrayAdapter mode_adapter =
- ArrayAdapter.createFromResource(getContext(), R.array.iperf_mode,
- R.layout.support_simple_spinner_dropdown_item);
- adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
- iperf3ModeSpinner.setAdapter(mode_adapter);
-
-
- getActivity().getSupportFragmentManager()
- .setFragmentResultListener("input", getViewLifecycleOwner(),
- new FragmentResultListener() {
- @Override
- public void onFragmentResult(@NonNull String requestKey,
- @NonNull Bundle result) {
-
- Iperf3RunResult iperf3RunResult =
- db.iperf3RunResultDao().getRunResult(result.getString("uid"));
- String logFileName = iperf3RunResult.input.iperf3LogFileName.split("_")[0];
- if (logFileName.equals("iperf3")) {
- logFileName = "";
- }
-
- iperf3EtIp.setText(iperf3RunResult.input.iperf3IP);
- iperf3EtPort.setText(iperf3RunResult.input.iperf3Port);
- iperf3EtBandwidth.setText(iperf3RunResult.input.iperf3Bandwidth);
- iperf3EtDuration.setText(iperf3RunResult.input.iperf3Duration);
- iperf3EtInterval.setText(iperf3RunResult.input.iperf3Interval);
- iperf3EtBytes.setText(iperf3RunResult.input.iperf3Bytes);
- iperf3EtStreams.setText(iperf3RunResult.input.streams);
- iperf3Cport.setText(iperf3RunResult.input.iperf3Cport);
-
- iperf3Reverse.setChecked(iperf3RunResult.input.iperf3Reverse);
- iperf3BiDir.setChecked(iperf3RunResult.input.iperf3BiDir);
- iperf3OneOff.setChecked(iperf3RunResult.input.iperf3OneOff);
- protocolSpinner.setSelection(iperf3RunResult.input.iperf3IdxProtocol);
- iperf3ModeSpinner.setSelection(iperf3RunResult.input.iperf3IdxMode);
-
- writeToSP();
- }
- });
- iperf3EtIp.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3IP, null));
- iperf3EtPort.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3PORT, null));
- iperf3EtBandwidth.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3BANDWIDTH, null));
- iperf3EtDuration.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3DURATION, null));
- iperf3EtInterval.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3INTERVAL, null));
- iperf3EtBytes.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3BYTES, null));
- iperf3EtStreams.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3STREAMS, null));
- iperf3Cport.setText(spg.getSharedPreference(SPType.iperf3_sp).getString(IPERF3CPORT, null));
-
- iperf3BiDir.setChecked(spg.getSharedPreference(SPType.iperf3_sp).getBoolean(IPERF3BIDIR, false));
- iperf3Reverse.setChecked(spg.getSharedPreference(SPType.iperf3_sp).getBoolean(IPERF3REVERSE, false));
- iperf3OneOff.setChecked(spg.getSharedPreference(SPType.iperf3_sp).getBoolean(IPERF3ONEOFF, false));
- protocolSpinner.setSelection(spg.getSharedPreference(SPType.iperf3_sp).getInt(IPERF3IDXPROTOCOL, 0));
- iperf3ModeSpinner.setSelection(spg.getSharedPreference(SPType.iperf3_sp).getInt(IPERF3IDXMODE, 0));
-
-
- try {
- Os.setenv("TMPDIR", String.valueOf(getActivity().getCacheDir()), true);
- } catch (ErrnoException e) {
- Log.d(TAG,e.toString());
- }
- return v;
- }
-
- public void showInstances(View view) {
- Bundle bundle = new Bundle();
- bundle.putStringArrayList("iperf3List", uids);
-
- NavController navController;
-
- NavHostFragment navHostFragment =
- (NavHostFragment) getActivity().getSupportFragmentManager()
- .findFragmentById(R.id.fragmentContainerView);
- navController = navHostFragment.getNavController();
-
- navController.navigate(R.id.runners_list, bundle);
- }
-
- private boolean isModeSpinnerClient() {
- String status = iperf3ModeSpinner.getSelectedItem().toString();
- return status.equals("Client");
- }
-
- public void executeIperfCommand(View view) {
- String[] command = parseInput().split(" ");
-
- String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath() + "/omnt/iperf3LP/";
-
- if(input.iperf3Json){
- try {
- Files.createDirectories(Paths.get(path));
- } catch (IOException e) {
- Toast.makeText(requireContext(),"Could not create Dir files!", Toast.LENGTH_SHORT).show();
- }
- }
-
- // create the log file;
-
- String iperf3WorkerID = input.uuid;
-
- input.iperf3LineProtocolFile = path + iperf3WorkerID + ".txt";
- Data.Builder iperf3Data = new Data.Builder();
- iperf3Data.putStringArray("commands", command);
- iperf3Data.putString("iperf3WorkerID", iperf3WorkerID);
- iperf3Data.putString("rawIperf3file", rawIperf3file);
- iperf3Data.putString("iperf3LineProtocolFile", input.iperf3LineProtocolFile);
- iperf3Data.putString("measurementName", input.measurementName);
- iperf3Data.putString("ip", input.iperf3IP);
- iperf3Data.putString("port", input.iperf3Port);
- iperf3Data.putString("bandwidth", input.iperf3Bandwidth);
- iperf3Data.putString("duration", input.iperf3Duration);
- iperf3Data.putString("interval", input.iperf3Interval);
- iperf3Data.putString("bytes", input.iperf3Bytes);
- iperf3Data.putString("protocol", protocolSpinner.getSelectedItem().toString());
- iperf3Data.putBoolean("rev", input.iperf3Reverse);
- iperf3Data.putBoolean("biDir", input.iperf3BiDir);
- iperf3Data.putBoolean("oneOff", input.iperf3OneOff);
- iperf3Data.putString("client", iperf3ModeSpinner.getSelectedItem().toString());
- iperf3Data.putString("timestamp", input.timestamp.toString());
- iperf3Data.putString("protocol", protocolSpinner.getSelectedItem().toString());
- iperf3Data.putString("cport", input.iperf3Cport);
-
- ListenableFuture> status = iperf3WM.getWorkInfosByTag("iperf3Run");
-
-/* try {
- for (WorkInfo workInfo : status.get()) {
- if (workInfo.getState().equals(WorkInfo.State.RUNNING)) {
- Toast.makeText(getContext(), "iperf3 Test is running!", Toast.LENGTH_SHORT)
- .show();
- return;
- }
- }
- } catch (ExecutionException | InterruptedException e) {
- Log.d(TAG,e.toString());
-;
- }*/
-
- uids.add(0, iperf3WorkerID);
- iperf3Data.putInt("notificationID", uids.size());
-
-
- OneTimeWorkRequest iperf3WR =
- new OneTimeWorkRequest
- .Builder(Iperf3Worker.class)
- .setInputData(iperf3Data.build())
- .addTag("iperf3Run")
- .addTag(iperf3WorkerID)
- .build();
- OneTimeWorkRequest iperf3LP =
- new OneTimeWorkRequest
- .Builder(Iperf3ToLineProtocolWorker.class)
- .setInputData(iperf3Data.build())
- .build();
- OneTimeWorkRequest iperf3UP =
- new OneTimeWorkRequest
- .Builder(Iperf3UploadWorker.class)
- .setInputData(iperf3Data.build())
- .addTag("iperf3")
- .build();
-
- iperf3RunResultDao.insert(
- new Iperf3RunResult(iperf3WorkerID, -100, false, input, input.timestamp));
-
-
-
- if (spg.getSharedPreference(SPType.logging_sp).getBoolean("enable_influx", false) && input.iperf3Json) {
- iperf3WM.beginWith(iperf3WR).then(iperf3LP).then(iperf3UP).enqueue();
- } else if(input.iperf3Json) {
- iperf3WM.beginWith(iperf3WR).then(iperf3LP).enqueue();
- } else {
- iperf3WM.beginWith(iperf3WR).enqueue();
- }
-
-
-
- Handler progressbarHandler = new Handler(Looper.myLooper());
-
- iperf3WM.getWorkInfoByIdLiveData(iperf3WR.getId()).observeForever(workInfo -> {
- int iperf3_result;
- iperf3_result = workInfo.getOutputData().getInt("iperf3_result", -100);
- if (workInfo.getState().equals(WorkInfo.State.CANCELLED)) {
- iperf3_result = -1;
- }
- iperf3RunResultDao.updateResult(iperf3WorkerID, iperf3_result);
- Log.d(TAG, "onChanged: iperf3_result: " + iperf3_result);
- if (iperf3_result == -100) {
- progressIndicator.setVisibility(LinearProgressIndicator.VISIBLE);
- if (!isModeSpinnerClient()) {
- progressbarHandler.postDelayed(progressbarUpdate, SHOW_PROGRESSBAR);
- }
- } else if (iperf3_result != 0) {
- progressIndicator.setIndicatorColor(failedColors);
- progressbarHandler.postDelayed(progressbarUpdate, SHOW_PROGRESSBAR);
-
- } else {
- progressIndicator.setIndicatorColor(succesColors);
- progressbarHandler.postDelayed(progressbarUpdate, SHOW_PROGRESSBAR);
- }
-
- });
- iperf3WM.getWorkInfoByIdLiveData(iperf3UP.getId()).observeForever(workInfo -> {
- boolean iperf3_upload;
- iperf3_upload = workInfo.getOutputData().getBoolean("iperf3_upload", false);
- Log.d(TAG, "onChanged: iperf3_upload: " + iperf3_upload);
- iperf3RunResultDao.updateUpload(iperf3WorkerID, iperf3_upload);
- });
-
-
- }
-
- private String getKeyFromId(String s, String value) {
- String key = "";
- switch (s) {
- case "iperf3_logfile":
- key = "--logfile";
- input.measurementName = value;
- break;
- case "iperf3_streams":
- key = "-P";
- input.streams = value;
- break;
- case "iperf3_ip":
- key = "-c";
- input.iperf3IP = value;
- break;
- case "iperf3_port":
- key = "-p";
- input.iperf3Port = value;
- break;
- case "iperf3_bandwidth":
- key = "-b";
- input.iperf3Bandwidth = value;
- break;
- case "iperf3_duration":
- key = "-t";
- input.iperf3Duration = value;
- break;
- case "iperf3_interval":
- key = "-i";
- input.iperf3Interval = value;
- break;
- case "iperf3_bytes":
- key = "-n";
- input.iperf3Bytes = value;
- break;
- case "iperf3_cport":
- key = "--cport";
- input.iperf3Cport = value;
- break;
- }
- return key;
- }
-
- private String parseInput() {
- List stb = new LinkedList<>();
- for (EditText et : editTexts) {
- String value = et.getText().toString();
- if (!value.equals("")) {
- String s = getResources().getResourceEntryName(et.getId());
- String key = getKeyFromId(s, value);
- if (s.equals("iperf3_bandwidth")) {
- value += "M";
- }
- stb.add(key);
- stb.add(value);
- }
- }
-
- String protocol = protocolSpinner.getSelectedItem().toString();
- if (!protocol.equals("TCP")) {
- stb.add("--" + protocol.toLowerCase());
- }
- input.iperf3IdxProtocol = protocolSpinner.getSelectedItemPosition();
-
- input.timestamp = new Timestamp(System.currentTimeMillis());
- String iperf3TS = input.timestamp.toString().replace(" ", "_").replace(":", "_");
-
- input.uuid = UUID.randomUUID().toString();
-
- input.measurementName = "Iperf3";
- this.logFileName = String.format("iperf3_%s_%s.json", iperf3TS, input.uuid);
-
- input.iperf3LogFileName = this.logFileName;
- this.rawIperf3file = this.logFileDir + this.logFileName;
- input.iperf3rawIperf3file = this.rawIperf3file;
-
- stb.add("--logfile");
- stb.add(this.rawIperf3file);
-
- input.iperf3BiDir = false;
- input.iperf3Reverse = false;
- input.iperf3OneOff = false;
- input.iperf3Json = true;
-
- if (!isModeSpinnerClient()) {
- stb.add("-s");
- input.iperf3IdxMode = iperf3ModeSpinner.getSelectedItemPosition();
- }
- if (iperf3BiDir.isChecked()) {
- stb.add("--bidir");
- input.iperf3BiDir = true;
- }
- if (iperf3Reverse.isChecked()) {
- stb.add("--reverse");
- input.iperf3Reverse = true;
- }
- if (iperf3OneOff.isChecked()) {
- stb.add("--one-off");
- input.iperf3OneOff = true;
- }
- stb.add("--json-stream");
-
- stb.add("--connect-timeout");
- stb.add("500");
-
-
- String joined = String.join(" ", stb);
-
- Log.d(TAG, "parseInput: joined command " + joined);
- input.iperf3Command = joined;
-
-
- return joined;
- }
-
- @Override
- public void onSaveInstanceState(@NonNull Bundle outState) {
- super.onSaveInstanceState(outState);
- }
-
- private void writeToSP() {
- SharedPreferences.Editor editor = spg.getSharedPreference(SPType.iperf3_sp).edit();
- editor.putInt(IPERF3IDXPROTOCOL, protocolSpinner.getSelectedItemPosition());
- editor.putInt(IPERF3IDXMODE, iperf3ModeSpinner.getSelectedItemPosition());
- editor.putString(IPERF3IP, iperf3EtIp.getText().toString());
- editor.putString(IPERF3PORT, iperf3EtPort.getText().toString());
- editor.putString(IPERF3BANDWIDTH, iperf3EtBandwidth.getText().toString());
- editor.putString(IPERF3DURATION, iperf3EtDuration.getText().toString());
- editor.putString(IPERF3INTERVAL, iperf3EtInterval.getText().toString());
- editor.putString(IPERF3BYTES, iperf3EtBytes.getText().toString());
- editor.putString(IPERF3STREAMS, iperf3EtStreams.getText().toString());
- editor.putString(IPERF3CPORT, iperf3Cport.getText().toString());
-
- editor.putBoolean(IPERF3BIDIR, iperf3BiDir.isChecked());
- editor.putBoolean(IPERF3REVERSE, iperf3Reverse.isChecked());
- editor.putBoolean(IPERF3ONEOFF, iperf3OneOff.isChecked());
- editor.apply();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- if(this.isResumed())
- writeToSP();
- }
-
-
-
- public static class Iperf3Input {
- public boolean iperf3BiDir;
- public boolean iperf3Reverse;
- public boolean iperf3Json;
- public boolean iperf3OneOff;
- public int iperf3IdxMode;
- public int iperf3IdxProtocol;
- public String uuid;
- public String iperf3Command;
- public String iperf3rawIperf3file;
- public String iperf3LogFileName;
- public String measurementName;
- public String iperf3IP;
- public String iperf3Port;
- public String iperf3Bandwidth;
- public String iperf3LineProtocolFile;
- public String iperf3Duration;
- public String iperf3Interval;
- public String iperf3Bytes;
- public Timestamp timestamp;
- public String streams;
- public String iperf3Cport;
- private List getFields(){
- List fields = Arrays.asList(Iperf3Input.class.getDeclaredFields());
- fields.sort((o1, o2) -> {
- return o1.toGenericString().compareTo(o2.toGenericString());
- });
- return fields;
- }
- private LinearLayout getTextView(String name, String value, Context ct){
- LinearLayout mainLL = new LinearLayout(ct);
- mainLL.setOrientation(LinearLayout.HORIZONTAL);
-
-
- LinearLayout.LayoutParams parameterLayoutName = new LinearLayout.LayoutParams(
- 0,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- parameterLayoutName.weight = 1F;
- TextView parameterName = new TextView(ct);
- parameterName.setTextIsSelectable(true);
- parameterName.setText(String.format("%s", name));
- parameterName.setLayoutParams(parameterLayoutName);
- TextView parameterValue = new TextView(ct);
- parameterValue.setTextIsSelectable(true);
- parameterValue.setText(String.format("%s", value));
- LinearLayout.LayoutParams parameterLayoutValue = new LinearLayout.LayoutParams(
- 0,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- parameterLayoutValue.weight = 3F;
- parameterValue.setLayoutParams(parameterLayoutValue);
-
- mainLL.addView(parameterName);
- mainLL.addView(parameterValue);
- return mainLL;
- }
- private LinearLayout getTextViewValue(String key, String value, Context ct){
- LinearLayout mainLL = new LinearLayout(ct);
- mainLL.setOrientation(LinearLayout.HORIZONTAL);
- mainLL.setFocusable(false);
- mainLL.setFocusedByDefault(false);
-
- TextView parameterValue = new TextView(ct);
-
- parameterValue.setTextIsSelectable(true);
- parameterValue.setText(String.format("%s", value));
- LinearLayout.LayoutParams parameterLayoutValue = new LinearLayout.LayoutParams(
- 0,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- parameterValue.setPadding(5, 5, 5, 5);
- parameterLayoutValue.setMargins(0, 0, 10, 10);
- parameterLayoutValue.weight = 1F;
- parameterValue.setLayoutParams(parameterLayoutValue);
-
- mainLL.addView(parameterValue);
- return mainLL;
- }
- public LinearLayout getInputAsLinearLayoutKeyValue(LinearLayout mainLL, Context ct){
- mainLL.setOrientation(LinearLayout.VERTICAL);
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
- 0,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- layoutParams.weight = 8F;
- mainLL.setLayoutParams(layoutParams);
- String[] protocol =
- ct.getResources().getStringArray(R.array.iperf_protocol);
- String[] mode = ct.getResources().getStringArray(R.array.iperf_mode);
- for(Field parameter: getFields()){
- try {
- Object parameterValueObj = parameter.get(this);
- if(parameterValueObj == null){
- continue;
- }
-
- String parameterName = parameter.getName().replace("iperf3", "");
- if(parameterName.equals("measurementName")
- || parameterName.equals("rawIperf3file")
- || parameterName.equals("LogFileName")
- || parameterName.equals("Command")
- || parameterName.equals("LineProtocolFile")) continue;
-
- String parameterValue = parameter.get(this).toString();
- if(parameterValue.equals("false")){
- continue;
- }
- if(parameterName.equals("IdxProtocol")){
- parameterName = "Protocol";
- parameterValue = protocol[Integer.parseInt(parameterValue)];
- }
-
- if(parameterName.equals("IdxMode")){
- parameterName = "Mode";
- parameterValue = mode[Integer.parseInt(parameterValue)];
- }
- mainLL.addView(getTextView(
- parameterName,
- parameterValue,
- ct));
-
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
- return mainLL;
- }
-
- public LinearLayout getInputAsLinearLayoutValue(LinearLayout mainLL, Context ct){
- mainLL.setOrientation(LinearLayout.HORIZONTAL);
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
- 0,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- layoutParams.weight = 10F;
- mainLL.setLayoutParams(layoutParams);
- String[] protocol =
- ct.getResources().getStringArray(R.array.iperf_protocol);
- String[] mode = ct.getResources().getStringArray(R.array.iperf_mode);
- for(Field parameter: getFields()){
- try {
- Object parameterValueObj = parameter.get(this);
- if(parameterValueObj == null){
- continue;
- }
-
- String parameterName = parameter.getName().replace("iperf3", "");
- if(parameterName.equals("measurementName")
- || parameterName.equals("rawIperf3file")
- || parameterName.equals("LogFileName")
- || parameterName.equals("Command")
- || parameterName.equals("LineProtocolFile")
- || parameterName.equals("timestamp")
- || parameterName.equals("uuid")) continue;
-
- String parameterValue = parameter.get(this).toString();
- if(parameterValue.equals("false")){
- continue;
- }
- if(parameterName.equals("IdxProtocol")){
- parameterName = "Protocol";
- parameterValue = protocol[Integer.parseInt(parameterValue)];
- }
-
- if(parameterName.equals("IdxMode")){
- parameterName = "Mode";
- parameterValue = mode[Integer.parseInt(parameterValue)];
- }
-
- if(parameterValue.equals("true")){
- parameterValue = parameterName;
- }
-
- mainLL.addView(getTextViewValue(
- parameterName,
- parameterValue,
- ct));
-
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
- return mainLL;
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Input.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Input.java
new file mode 100644
index 00000000..bfef1ea8
--- /dev/null
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Input.java
@@ -0,0 +1,449 @@
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+
+import android.os.Environment;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.widget.LinearLayout;
+
+import androidx.annotation.NonNull;
+import androidx.work.Data;
+
+
+import org.checkerframework.checker.units.qual.A;
+
+import java.lang.reflect.Field;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.StringJoiner;
+import java.util.UUID;
+
+
+public class Iperf3Input implements Parcelable {
+ public static final String[] EXCLUDED_FIELDS = {
+ "measurementName", "rawFile", "logFileName", "command", "lineProtocolFile",
+ "context", "timestamp", "uuid", "cardView", "main", "EXCLUDED_FIELDS"
+ };
+
+
+ public static final String rootPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath();
+ public static final String jsonDirPath = rootPath+"/omnt/iperf3/json/";
+ public static final String lineProtocolDirPath = rootPath+"/omnt/iperf3/lineprotocol/";
+
+ public static final String IPERF3IP = "iperf3IP";
+ public static final String IPERF3PORT = "iperf3Port";
+ public static final String IPERF3BANDWIDTH = "iperf3Bandwidth";
+ public static final String IPERF3DURATION = "iperf3Duration";
+ public static final String IPERF3INTERVAL = "iperf3Interval";
+ public static final String IPERF3BYTES = "iperf3Bytes";
+ public static final String IPERF3STREAMS = "iperf3Streams";
+ public static final String IPERF3DIRECTION = "iperf3Direction";
+ public static final String IPERF3ONEOFF = "iperf3OneOff";
+ public static final String IPERF3PROTOCOL = "iperf3IdxProtocol";
+ public static final String IPERF3MODE = "iperf3IdxMode";
+ public static final String IPERF3CPORT = "iperf3cport";
+ public static final String IPERF3UUID = "iperf3UUID";
+ public static final String IPERF3TIMESTAMP = "iperf3Timestamp";
+
+
+ protected Iperf3Input(Parcel in) {
+ isJson = in.readBoolean();
+ isOneOff = in.readBoolean();
+ mode = Iperf3Mode.valueOf(in.readString());
+ protocol = Iperf3Protocol.valueOf(in.readString());
+ direction = Iperf3Direction.valueOf(in.readString());
+ rawFile = in.readString();
+ ip = in.readString();
+ port = in.readString();
+ bandwidth = in.readString();
+ duration = in.readString();
+ interval = in.readString();
+ bytes = in.readString();
+ streams = in.readString();
+ cport = in.readString();
+ uuid = in.readString();
+ logFileName = in.readString();
+ measurementName = in.readString();
+ lineProtocolFile = in.readString();
+ timestamp = (Timestamp) in.readSerializable();
+ }
+
+ public static final Creator CREATOR = new Creator<>() {
+ @Override
+ public Iperf3Input createFromParcel(Parcel in) {
+ return new Iperf3Input(in);
+ }
+
+ @Override
+ public Iperf3Input[] newArray(int size) {
+ return new Iperf3Input[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int i) {
+ parcel.writeBoolean(isJson);
+ parcel.writeBoolean(isOneOff);
+ parcel.writeString(mode.toString());
+ parcel.writeString(protocol.toString());
+ parcel.writeString(direction.toString());
+ parcel.writeString(rawFile);
+ parcel.writeString(ip);
+ parcel.writeString(port);
+ parcel.writeString(bandwidth);
+ parcel.writeString(duration);
+ parcel.writeString(interval);
+ parcel.writeString(bytes);
+ parcel.writeString(streams);
+ parcel.writeString(cport);
+ parcel.writeString(uuid);
+ parcel.writeString(logFileName);
+ parcel.writeString(measurementName);
+ parcel.writeString(lineProtocolFile);
+ parcel.writeSerializable(timestamp);
+ }
+
+ public boolean isValid(){
+ return !ip.isEmpty();
+ }
+
+ public enum Iperf3Mode {
+ CLIENT,
+ SERVER,
+ UNDEFINED;
+ public String toPrettyPrint() {
+ return this.name().substring(0, 1).toUpperCase() + this.name().toLowerCase().substring(1);
+ }
+ }
+
+ public enum Iperf3Protocol {
+ TCP,
+ UDP,
+ UNDEFINED
+ }
+
+ public enum Iperf3Direction {
+ UP,
+ DOWN,
+ BIDIR,
+ UNDEFINED;
+ public String toPrettyPrint() {
+ return this.name().toLowerCase();
+ }
+ }
+
+ private boolean isJson;
+ private boolean isOneOff;
+ private Iperf3Mode mode = Iperf3Mode.UNDEFINED;
+ private Iperf3Protocol protocol = Iperf3Protocol.UNDEFINED;
+ private Iperf3Direction direction = Iperf3Direction.UNDEFINED;
+ private String rawFile;
+ private String ip;
+ private String port;
+ private String bandwidth;
+ private String duration;
+ private String interval;
+ private String bytes;
+ private String streams;
+ private String cport;
+
+ private String uuid;
+ private String logFileName;
+ private String measurementName;
+ private String lineProtocolFile;
+ private Timestamp timestamp;
+
+
+ public Iperf3Input() {
+ this.isJson = false;
+ this.isOneOff = false;
+ //if(uuid == null) this.uuid = UUID.randomUUID().toString();
+ this.uuid = "";
+ this.rawFile = jsonDirPath+this.uuid+".json";;
+ this.logFileName = "";
+ this.measurementName = "";
+ this.ip = "";
+ this.port = "";
+ this.bandwidth = "";
+ this.lineProtocolFile = lineProtocolDirPath+this.uuid+".txt";
+ this.duration = "";
+ this.interval = "";
+ this.bytes = "";
+ this.timestamp = new Timestamp(System.currentTimeMillis());
+ this.streams = "";
+ this.cport = "";
+ }
+
+ public void setMode(Iperf3Mode mode) {
+ this.mode = mode;
+ }
+
+ public void setJson(boolean json) {
+ this.isJson = json;
+ }
+
+ public void setOneOff(boolean oneOff) {
+ this.isOneOff = oneOff;
+ }
+
+ public void setDirection(Iperf3Direction direction) {
+ this.direction = direction;
+ }
+
+ public void setProtocol(Iperf3Protocol protocol) {
+ this.protocol = protocol;
+ }
+
+ public Iperf3Direction getDirection() {
+ return direction;
+ }
+
+
+ public Iperf3Protocol getProtocol() {
+ return protocol;
+ }
+
+ public Iperf3Mode getMode() {
+ return mode;
+ }
+
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ this.rawFile = jsonDirPath+this.uuid+".json";
+ this.lineProtocolFile = lineProtocolDirPath+this.uuid+".txt";
+ }
+
+
+ public void setRawFile(String rawFile) {
+ this.rawFile = rawFile;
+ }
+
+ public void setLogFileName(String logFileName) {
+ this.logFileName = logFileName;
+ }
+
+ public void setMeasurementName(String measurementName) {
+ this.measurementName = measurementName;
+ }
+
+ public void setIp(String ip) {
+ this.ip = ip;
+ }
+
+ public void setPort(String port) {
+ this.port = port;
+ }
+
+ public void setBandwidth(String bandwidth) {
+ this.bandwidth = bandwidth;
+ }
+
+ public void setLineProtocolFile(String lineProtocolFile) {
+ this.lineProtocolFile = lineProtocolFile;
+ }
+
+ public void setDuration(String duration) {
+ this.duration = duration;
+ }
+
+ public void setInterval(String interval) {
+ this.interval = interval;
+ }
+
+ public void setBytes(String bytes) {
+ this.bytes = bytes;
+ }
+
+ public void setTimestamp(Timestamp timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public void setStreams(String streams) {
+ this.streams = streams;
+ }
+
+ public void setCport(String cport) {
+ this.cport = cport;
+ }
+
+
+ public boolean isJson() {
+ return isJson;
+ }
+
+ public boolean isOneOff() {
+ return isOneOff;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public String getRawFile() {
+ return rawFile;
+ }
+
+ public String getLogFileName() {
+ return logFileName;
+ }
+
+ public String getMeasurementName() {
+ return measurementName;
+ }
+
+ public String getIp() {
+ return ip;
+ }
+
+ public String getPort() {
+ return port;
+ }
+
+ public String getBandwidth() {
+ return bandwidth;
+ }
+
+ public String getLineProtocolFile() {
+ return lineProtocolFile;
+ }
+
+ public String getDuration() {
+ return duration;
+ }
+
+ public String getInterval() {
+ return interval;
+ }
+
+ public String getBytes() {
+ return bytes;
+ }
+
+ public Timestamp getTimestamp() {
+ return timestamp;
+ }
+
+ public String getStreams() {
+ return streams;
+ }
+
+ public String getCport() {
+ return cport;
+ }
+
+ public List getFields() {
+ List fields = Arrays.asList(Iperf3Input.class.getDeclaredFields());
+ fields.sort((o1, o2) -> o1.toGenericString().compareTo(o2.toGenericString()));
+ return fields;
+ }
+
+
+ public Data.Builder getInputAsDataBuilder() {
+ Data.Builder data = new Data.Builder();
+ for (Field parameter : getFields()) {
+ try {
+ Object parameterValueObj = parameter.get(this);
+ if (parameterValueObj == null) {
+ continue;
+ }
+
+ String parameterName = parameter.getName().replace("iperf3", "");
+ if (Arrays.asList(EXCLUDED_FIELDS).contains(parameterName)) continue;
+
+ String parameterValue = parameter.get(this).toString();
+ if (parameterValue.equals("false") || parameterValue.isEmpty()) {
+ continue;
+ }
+
+ data.putString(parameterName, parameterValue);
+
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ data.putStringArray("command", getInputAsCommand());
+ data.putString("uuid", uuid);
+ return data;
+ }
+
+ public String[] getInputAsCommand(){
+ ArrayList command = new ArrayList<>();
+ //command.add("iperf3");
+ switch (mode) {
+ case CLIENT:
+ command.add("-c");
+ if(!ip.isEmpty()) command.add(ip);
+ break;
+ case SERVER:
+ command.add("-s");
+ break;
+ }
+ if(port != null && !port.isEmpty()){
+ command.add("-p");
+ command.add(port);
+ }
+ if(bandwidth != null && !bandwidth.isEmpty()){
+ command.add("-b");
+ command.add(bandwidth);
+ }
+ if(duration != null && !duration.isEmpty()){
+ command.add("-t");
+ command.add(duration);
+ }
+ if(interval != null && !interval.isEmpty()){
+ command.add("-i");
+ command.add(interval);
+ }
+ if(bytes != null && !bytes.isEmpty()){
+ command.add("-n");
+ command.add(bytes);
+ }
+ if(streams != null && !streams.isEmpty()){
+ command.add("-P");
+ command.add(streams);
+ }
+ if(cport != null && !cport.isEmpty()){
+ command.add("-B");
+ command.add(cport);
+ }
+
+ switch (direction){
+ case DOWN:
+ command.add("--reverse");
+ break;
+ case BIDIR:
+ command.add("--bidir");
+ break;
+ case UP:
+ break;
+ }
+
+ switch (protocol){
+ case UDP:
+ command.add("-u");
+ break;
+ case TCP:
+ break;
+ }
+
+ command.add("--logfile");
+ command.add(rawFile);
+ command.add("--json-stream");
+ command.add("--connect-timeout");
+ command.add("500");
+ return command.toArray(new String[0]);
+ }
+
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3LibLoader.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3LibLoader.java
index c8d20e25..96075272 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3LibLoader.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3LibLoader.java
@@ -27,7 +27,7 @@ public class Iperf3LibLoader {
"iperf3.17.1"
);
- protected static synchronized void load() {
+ public static synchronized void load() {
if (done) {
return;
}
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Parser.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Parser.java
index 781ade6b..4487fcdc 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Parser.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Parser.java
@@ -1,5 +1,12 @@
package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+import android.content.Context;
+import android.os.FileObserver;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import org.json.JSONException;
import org.json.JSONObject;
import java.beans.PropertyChangeListener;
@@ -8,68 +15,110 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
+import java.io.IOException;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Converter.IntervalsConverter;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3RunResult;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Error;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Interval;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.start.Start;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3ResultsDataBase;
public class Iperf3Parser {
-
+ private static final String TAG = "Iperf3Parser";
private final String pathToFile;
private final File file;
private BufferedReader br = null;
private PropertyChangeSupport support;
private Start start;
private final Intervals intervals = new Intervals();
- Iperf3Parser(String pathToFile) {
+ private Iperf3ResultsDataBase db;
+ private Context context;
+ private Iperf3Input iperf3Input;
+ private FileObserver fileObserver;
+ public Iperf3Parser(Context context, String pathToFile, Iperf3Input iperf3Input) {
+ this.context = context;
this.pathToFile = pathToFile;
this.file = new File(this.pathToFile);
- try {
- br = new BufferedReader(new FileReader(file));
- } catch (FileNotFoundException ex) {
- System.out.println("File not found");
- return;
- }
this.support = new PropertyChangeSupport(this);
+ this.db = Iperf3ResultsDataBase.getDatabase(this.context);
+ this.iperf3Input = iperf3Input;
+ this.fileObserver = null;
}
+
+
public void parse(){
- String line;
- try {
- while ((line = br.readLine()) != null) {
- JSONObject obj = new JSONObject(line);
- String event = obj.getString("event");
- switch (event) {
- case "start":
- start = new Start();
- JSONObject startData = obj.getJSONObject("data");
- start.parseStart(startData);
- break;
- case "interval":
- Interval interval = new Interval();
- JSONObject intervalData = obj.getJSONObject("data");
- interval.parse(intervalData);
- support.firePropertyChange("interval", null, interval);
- intervals.addInterval(interval);
- break;
- case "end":
- System.out.println("End");
- break;
- case "error":
- Error error = new Error();
- String errorString = obj.getString("data");
- error.parse(errorString);
- support.firePropertyChange("error", null, error);
+ Log.i(TAG, "Parsing file");
+
+
+ fileObserver = new FileObserver(new File(pathToFile),
+ FileObserver.ALL_EVENTS) {
+ @Override
+ public void onEvent(int i, @Nullable String s) {
+ switch (i){
+ case FileObserver.CREATE:
+ Log.i(TAG, "onEvent: File created by iPerf3");
break;
- default:
- System.out.println("Unknown event");
+ case FileObserver.MODIFY:
+ Log.i(TAG, "onEvent: File modified by iPerf3");
+
+ try {
+ br = new BufferedReader(new FileReader(file));
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "onEvent: File not found!");
+ }
+ String line;
+ try {
+ while ((line = br.readLine()) != null) {
+ JSONObject obj = new JSONObject(line);
+ String event = obj.getString("event");
+ switch (event) {
+ case "start":
+ start = new Start();
+ JSONObject startData = obj.getJSONObject("data");
+ start.parseStart(startData);
+ break;
+ case "interval":
+ Interval interval = new Interval();
+ JSONObject intervalData = obj.getJSONObject("data");
+ interval.parse(intervalData);
+ support.firePropertyChange("interval", null, interval);
+ intervals.addInterval(interval);
+ db.iperf3RunResultDao().updateIntervals(iperf3Input.getUuid(), intervals.getIntervalArrayList());
+ Log.d(TAG, "parse: interval added to db for "+iperf3Input.getUuid());
+ break;
+ case "end":
+ System.out.println("End");
+ break;
+ case "error":
+ Error error = new Error();
+ String errorString = obj.getString("data");
+ error.parse(errorString);
+ support.firePropertyChange("error", null, error);
+ break;
+ default:;
+ System.out.println("Unknown event");
+ break;
+ }
+ }
+ } catch (JSONException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ this.stopWatching();
+
break;
}
}
- } catch (Exception e) {
- System.out.println("Error reading file");
- }
+ };
+ fileObserver.startWatching();
+
+
+
}
public Intervals getIntervals() {
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3RecyclerViewAdapter.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3RecyclerViewAdapter.java
index 0ab33dce..1c6694db 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3RecyclerViewAdapter.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3RecyclerViewAdapter.java
@@ -9,7 +9,10 @@
package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
import android.annotation.SuppressLint;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
@@ -23,21 +26,30 @@
import android.widget.Toast;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.cardview.widget.CardView;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
-import androidx.preference.PreferenceManager;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.RecyclerView;
import androidx.work.Data;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import com.google.android.material.progressindicator.LinearProgressIndicator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Fragments.Output.Iperf3LogFragment;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Interval;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Worker.Iperf3UploadWorker;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3ResultsDataBase;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3RunResult;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Database.Iperf3RunResultDao;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SPType;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesGrouper;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R;
@@ -46,18 +58,20 @@ public class Iperf3RecyclerViewAdapter
extends RecyclerView.Adapter {
private final String TAG = "Iperf3RecyclerViewAdapter";
private final Iperf3ResultsDataBase db;
- private final ArrayList uids;
+ private ArrayList uids;
private Context context;
- private final FragmentActivity c;
+ private FragmentActivity c;
private final HashMap selectedRuns;
private final HashMap selectedCardViews;
private final FloatingActionButton uploadBtn;
+ private BroadcastReceiver receiver;
public Iperf3RecyclerViewAdapter(FragmentActivity c, ArrayList uids,
FloatingActionButton uploadBtn) {
this.c = c;
+ if(uids == null) uids = new ArrayList<>();
this.uids = uids;
- this.db = Iperf3ResultsDataBase.getDatabase(context);
+ this.db = Iperf3ResultsDataBase.getDatabase(this.c.getApplicationContext());
this.selectedRuns = new HashMap<>();
this.selectedCardViews = new HashMap<>();
this.uploadBtn = uploadBtn;
@@ -83,7 +97,7 @@ public void onClick(View view) {
Iperf3RunResult runResult = iperf3RunResultDao.getRunResult(uid);
Data.Builder data = new Data.Builder();
- data.putString("iperf3LineProtocolFile", runResult.input.iperf3LineProtocolFile);
+ data.putString("iperf3LineProtocolFile", runResult.input.getLineProtocolFile());
OneTimeWorkRequest iperf3UP =
new OneTimeWorkRequest.Builder(Iperf3UploadWorker.class)
.setInputData(data.build())
@@ -109,6 +123,19 @@ public void onClick(View view) {
}
});
+ for(String uid: uids){
+ LiveData liveData = db.iperf3RunResultDao().getIntervals(uid);
+ Observer observer = new Observer() {
+ @Override
+ public void onChanged(Intervals intervals) {
+ notifyDataSetChanged();
+ }
+ };
+ liveData.observe(c, observer);
+ }
+
+
+
}
@@ -131,6 +158,52 @@ public boolean isNightMode(Context context) {
return nightModeFlags == Configuration.UI_MODE_NIGHT_YES;
}
+ private TextView createTextView(Context ct, String text, float weight) {
+ TextView textView = new TextView(ct);
+ textView.setText(text);
+ LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT);
+ layoutParams.weight = weight;
+ textView.setLayoutParams(layoutParams);
+ return textView;
+ }
+
+ private LinearLayout getTextViewValue(String key, String value, Context ct) {
+ LinearLayout mainLL = new LinearLayout(ct);
+ mainLL.setOrientation(LinearLayout.HORIZONTAL);
+ mainLL.setFocusable(false);
+ mainLL.setFocusedByDefault(false);
+
+ TextView parameterValue = createTextView(ct, value, 1F);
+ parameterValue.setTextIsSelectable(true);
+ parameterValue.setPadding(5, 5, 5, 5);
+ LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) parameterValue.getLayoutParams();
+ layoutParams.setMargins(0, 0, 10, 10);
+
+ mainLL.addView(parameterValue);
+ return mainLL;
+ }
+
+ public LinearLayout getInputAsLinearLayoutValue(LinearLayout mainLL, Context ct, Iperf3Input input) {
+ mainLL.setOrientation(LinearLayout.HORIZONTAL);
+ LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
+ 0,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+ layoutParams.weight = 10F;
+ mainLL.setLayoutParams(layoutParams);
+
+ mainLL.addView(getTextViewValue(Iperf3Input.IPERF3IP.replace("iperf3", ""), input.getIp(), ct));
+ mainLL.addView(getTextViewValue(Iperf3Input.IPERF3PORT.replace("iperf3", ""), input.getPort(), ct));
+ mainLL.addView(getTextViewValue(Iperf3Input.IPERF3PROTOCOL.replace("iperf3", ""), input.getProtocol().toString(), ct));
+ mainLL.addView(getTextViewValue(Iperf3Input.IPERF3MODE.replace("iperf3", ""), input.getMode().toPrettyPrint(), ct));
+ mainLL.addView(getTextViewValue(Iperf3Input.IPERF3DIRECTION.replace("iperf3", ""), input.getDirection().toPrettyPrint(), ct));
+ mainLL.addView(getTextViewValue(Iperf3Input.IPERF3BANDWIDTH.replace("iperf3", ""), input.getBandwidth(), ct));
+ mainLL.addView(getTextViewValue(Iperf3Input.IPERF3DURATION.replace("iperf3", ""), input.getDuration(), ct));
+
+
+ return mainLL;
+ }
+
+
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.iPerf3Parameters.removeAllViews();
@@ -149,12 +222,29 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
}
holder.measurement.setText("iPerf3");
- holder.timestamp.setText(test.input.timestamp.toString());
+ holder.timestamp.setText(test.input.getTimestamp().toString());
holder.runIcon.setImageDrawable(Iperf3Utils.getDrawableResult(context, test.result));
holder.uploadIcon.setImageDrawable(Iperf3Utils.getDrawableUpload(context, test.result, test.uploaded));
- holder.iPerf3Parameters = test.input.getInputAsLinearLayoutValue(holder.iPerf3Parameters, context);
+ holder.iPerf3Parameters = getInputAsLinearLayoutValue(holder.iPerf3Parameters, context, test.input);
+ IntentFilter filter = new IntentFilter(context.getPackageName() + ".broadcast.iperf3.INTERVAL");
+
+
+
+ Iperf3RunResult iperf3RunResult = db.iperf3RunResultDao().getRunResult(this.uids.get(position));
+ String duration = iperf3RunResult.input.getDuration();
+ if(duration == null || duration.equals("")) duration = "10";
+ int progress = 0;
+ try {
+ progress = (int) iperf3RunResult.intervals.get(iperf3RunResult.intervals.size()-1).getSum().getEnd();
+ } catch (Exception e) {}
+ holder.linearProgressIndicator.setMax(Integer.parseInt(duration));
+ holder.linearProgressIndicator.setProgress(progress);
+
+
+ this.c.registerReceiver(holder.broadcastReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
}
+
private Iperf3RunResult getItemByPosition(int position) {
return this.db.iperf3RunResultDao().getRunResult(this.uids.get(position));
}
@@ -172,6 +262,13 @@ public class ViewHolder extends RecyclerView.ViewHolder {
public ImageView uploadIcon;
private final LinearLayout linearLayout;
private LinearLayout iPerf3Parameters;
+ private String uid;
+ private LinearProgressIndicator linearProgressIndicator;
+ private BroadcastReceiver broadcastReceiver;
+
+ public LinearLayout getLinearLayout() {
+ return linearLayout;
+ }
private LinearLayout firstRow(LinearLayout ll){
measurement.setLayoutParams(
@@ -206,9 +303,19 @@ private LinearLayout thirdRow(LinearLayout ll){
return ll;
}
+
+ private LinearLayout fourthRow(LinearLayout ll){
+ ll.setOrientation(LinearLayout.HORIZONTAL);
+ linearProgressIndicator = new LinearProgressIndicator(context);
+ linearProgressIndicator.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 40));
+ ll.addView(linearProgressIndicator);
+
+
+ return ll;
+ }
+
public ViewHolder(View itemView) {
super(itemView);
- Log.d(TAG, "ViewHolder: " + itemView);
measurement = new TextView(context);
timestamp = new TextView(context);
iperf3State = new TextView(context);
@@ -223,6 +330,8 @@ public ViewHolder(View itemView) {
linearLayout.addView(firstRow(new LinearLayout(context)));
linearLayout.addView(secondRow(new LinearLayout(context)));
linearLayout.addView(thirdRow(new LinearLayout(context)));
+ linearLayout.addView(fourthRow(new LinearLayout(context)));
+
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
@@ -265,13 +374,15 @@ public void onClick(View v) {
bundle.putString("uid", uid);
Iperf3LogFragment test = new Iperf3LogFragment();
test.setArguments(bundle);
+
c.getSupportFragmentManager().beginTransaction()
.replace(R.id.fragmentContainerView, test, "iperf3LogFragment")
.addToBackStack("findThisFragment").commit();
}
});
-
+ int itemPos = getLayoutPosition();
+ if(uids.contains(itemPos)) uid = uids.get(getLayoutPosition());
}
}
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3ResultsDataBase.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3ResultsDataBase.java
deleted file mode 100644
index d9b01a29..00000000
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3ResultsDataBase.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2023 Peter Hasse
- * SPDX-FileCopyrightText: 2023 Johann Hackler
- * SPDX-FileCopyrightText: 2023 Fraunhofer FOKUS
- *
- * SPDX-License-Identifier: BSD-3-Clause-Clear
- */
-
-package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
-
-import android.content.Context;
-
-import androidx.room.Database;
-import androidx.room.Room;
-import androidx.room.RoomDatabase;
-
-@Database(
- entities = {Iperf3RunResult.class},
- version = 3
-)
-public abstract class Iperf3ResultsDataBase extends RoomDatabase {
- private static volatile Iperf3ResultsDataBase INSTANCE;
-
- static Iperf3ResultsDataBase getDatabase(final Context context) {
- if (INSTANCE == null) {
- synchronized (Iperf3ResultsDataBase.class) {
- if (INSTANCE == null) {
-
- INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
- Iperf3ResultsDataBase.class, "iperf3_result_database")
- .addTypeConverter(new Iperf3InputConverter())
- .allowMainThreadQueries()
- .build();
- }
- }
- }
- return INSTANCE;
- }
-
- public abstract Iperf3RunResultDao iperf3RunResultDao();
-}
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Service.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Service.java
new file mode 100644
index 00000000..a1a2d0da
--- /dev/null
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Service.java
@@ -0,0 +1,115 @@
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Build;
+import android.os.FileObserver;
+import android.os.IBinder;
+import android.util.Log;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+import androidx.core.app.NotificationCompat;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R;
+
+public class Iperf3Service extends Service {
+ public final static int FOREGROUND_SERVICE_TYPE = FOREGROUND_SERVICE_TYPE_SPECIAL_USE;
+ public final static int NOTIFICATION_ID = 1002;
+ private static final String CHANNEL_ID = "Iperf3ServiceChannel";
+ private static final String TAG = "Iperf3Service";
+ private ArrayList parsing = new ArrayList<>();
+ private FileObserver fileObserver;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ createNotificationChannel();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if(intent == null){
+ Toast.makeText(getApplicationContext(),"No intent!", Toast.LENGTH_SHORT).show();
+ return START_NOT_STICKY;
+ }
+ Iperf3Input iperf3Input = intent.getParcelableExtra("input");
+
+ if(iperf3Input == null){
+ Toast.makeText(getApplicationContext(),"No input data!", Toast.LENGTH_SHORT).show();
+ return START_NOT_STICKY;
+ }
+ Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
+ .setContentTitle("iPerf3 Service")
+ .setContentText("no active test")
+ .setSmallIcon(R.drawable.outline_speed_24)
+ .build();
+
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
+ startForeground(NOTIFICATION_ID, notification);
+ } else {
+ startForeground(NOTIFICATION_ID, notification, FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
+ }
+ try{
+ Files.createDirectories(Paths.get(Iperf3Input.jsonDirPath));
+ Files.createDirectories(Paths.get(Iperf3Input.lineProtocolDirPath));
+ } catch (IOException e){
+ Toast.makeText(getApplicationContext(),"Could not create Dir files!", Toast.LENGTH_SHORT).show();
+ }
+
+ Iperf3Executor iperf3Executor = new Iperf3Executor(getApplicationContext(), iperf3Input);
+ iperf3Executor.start();
+
+ fileObserver = new FileObserver(new File(Iperf3Input.jsonDirPath),
+ FileObserver.ALL_EVENTS) {
+ @Override
+ public void onEvent(int i, @Nullable String s) {
+ Log.i(TAG, "onEvent: " + i + " " + s);
+ switch (i){
+ case FileObserver.MODIFY:
+ Log.i(TAG, "onEvent: File modified by iPerf3");
+ Iperf3Parser iperf3Parser = new Iperf3Parser(getApplicationContext(), iperf3Input.getRawFile(), iperf3Input);
+ iperf3Parser.parse();
+ break;
+ }
+ }
+ };
+ fileObserver.startWatching();
+
+ return START_STICKY;
+ }
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ private void createNotificationChannel() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationChannel serviceChannel = new NotificationChannel(
+ CHANNEL_ID,
+ "Iperf3 Service Channel",
+ NotificationManager.IMPORTANCE_HIGH
+ );
+
+ NotificationManager manager = getSystemService(NotificationManager.class);
+ if (manager != null) {
+ manager.createNotificationChannel(serviceChannel);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Interval.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Interval.java
index 47d51b1a..26309c9b 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Interval.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Interval.java
@@ -2,6 +2,11 @@
import static de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Sum.SUM_TYPE.*;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.STREAM_TYPE;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Sum.SUM_TYPE;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Sum.Sum;
@@ -17,7 +22,7 @@
import org.json.JSONException;
import org.json.JSONObject;
-public class Interval {
+public class Interval implements Parcelable{
private final Streams streams;
private Sum sum;
public Sum sumBidirReverse;
@@ -26,6 +31,24 @@ public Interval(){
streams = new Streams();
}
+ protected Interval(Parcel in) {
+ streams = in.readParcelable(Streams.class.getClassLoader());
+ sum = in.readParcelable(Sum.class.getClassLoader());
+ sumBidirReverse = in.readParcelable(Sum.class.getClassLoader());
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public Interval createFromParcel(Parcel in) {
+ return new Interval(in);
+ }
+
+ @Override
+ public Interval[] newArray(int size) {
+ return new Interval[size];
+ }
+ };
+
private SUM_TYPE getSumType(JSONObject data) throws JSONException {
boolean sender = data.getBoolean("sender");
if(sender){
@@ -76,4 +99,16 @@ public Sum getSum() {
public Sum getSumBidirReverse() {
return sumBidirReverse;
}
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int i) {
+ parcel.writeParcelable(streams, i);
+ parcel.writeParcelable(sum, i);
+ parcel.writeParcelable(sumBidirReverse, i);
+ }
}
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Streams/Stream.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Streams/Stream.java
index 9ec8dba1..dfcd48c2 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Streams/Stream.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Streams/Stream.java
@@ -1,9 +1,14 @@
package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
import org.json.JSONException;
import org.json.JSONObject;
-public class Stream {
+public class Stream implements Parcelable {
private int socket;
private int start;
private double end;
@@ -17,6 +22,30 @@ public class Stream {
public Stream(){
}
+
+ protected Stream(Parcel in) {
+ socket = in.readInt();
+ start = in.readInt();
+ end = in.readDouble();
+ seconds = in.readDouble();
+ bytes = in.readLong();
+ bits_per_second = in.readDouble();
+ omitted = in.readBoolean();
+ sender = in.readBoolean();
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public Stream createFromParcel(Parcel in) {
+ return new Stream(in);
+ }
+
+ @Override
+ public Stream[] newArray(int size) {
+ return new Stream[size];
+ }
+ };
+
public void parse(JSONObject data) throws JSONException {
this.socket = data.getInt("socket");
this.start = data.getInt("start");
@@ -61,4 +90,21 @@ public void setStreamType(
STREAM_TYPE streamType) {
this.streamType = streamType;
}
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int i) {
+ parcel.writeInt(socket);
+ parcel.writeInt(start);
+ parcel.writeDouble(end);
+ parcel.writeDouble(seconds);
+ parcel.writeLong(bytes);
+ parcel.writeDouble(bits_per_second);
+ parcel.writeBoolean(omitted);
+ parcel.writeBoolean(sender);
+ }
}
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Streams/Streams.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Streams/Streams.java
index 4a07cf84..3660a470 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Streams/Streams.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Streams/Streams.java
@@ -1,5 +1,10 @@
package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.TCP.TCP_DL_STREAM;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.TCP.TCP_UL_STREAM;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.UDP.UDP_DL_STREAM;
@@ -9,12 +14,28 @@
import org.json.JSONException;
import org.json.JSONObject;
-public class Streams {
+public class Streams implements Parcelable {
private final ArrayList streams;
public Streams(){
this.streams = new ArrayList<>();
}
+ protected Streams(Parcel in) {
+ streams = in.createTypedArrayList(Stream.CREATOR);
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public Streams createFromParcel(Parcel in) {
+ return new Streams(in);
+ }
+
+ @Override
+ public Streams[] newArray(int size) {
+ return new Streams[size];
+ }
+ };
+
private STREAM_TYPE identifyStream(JSONObject data) throws JSONException {
boolean sender = data.getBoolean("sender");
if(sender){
@@ -71,4 +92,14 @@ public void addStream(Stream stream){
public Stream getStream(int i) {
return streams.get(i);
}
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int i) {
+ parcel.writeTypedList(streams);
+ }
}
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Streams/TCP/TCP_DL_STREAM.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Streams/TCP/TCP_DL_STREAM.java
index 93e27705..328c3e1c 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Streams/TCP/TCP_DL_STREAM.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Streams/TCP/TCP_DL_STREAM.java
@@ -1,5 +1,7 @@
package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.TCP;
+import android.annotation.SuppressLint;
+
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.STREAM_TYPE;
import org.json.JSONException;
@@ -9,6 +11,7 @@ public class TCP_DL_STREAM extends TCP_STREAM {
public TCP_DL_STREAM(){
super();
}
+
public void parse(JSONObject data) throws JSONException {
super.parse(data);
this.setStreamType(STREAM_TYPE.TCP_DL);
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Sum/Sum.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Sum/Sum.java
index c8f56f68..e99a96a1 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Sum/Sum.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/JSON/Interval/Sum/Sum.java
@@ -1,9 +1,14 @@
package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Sum;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
import org.json.JSONException;
import org.json.JSONObject;
-public class Sum {
+public class Sum implements Parcelable {
private int start;
private float end;
private float seconds;
@@ -14,6 +19,30 @@ public class Sum {
private SUM_TYPE sumType;
public Sum(){
}
+
+ protected Sum(Parcel in) {
+ start = in.readInt();
+ end = in.readFloat();
+ seconds = in.readFloat();
+ bytes = in.readLong();
+ bits_per_second = in.readDouble();
+ omitted = in.readBoolean();
+ sender = in.readBoolean();
+ sumType = SUM_TYPE.values()[in.readInt()];
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public Sum createFromParcel(Parcel in) {
+ return new Sum(in);
+ }
+
+ @Override
+ public Sum[] newArray(int size) {
+ return new Sum[size];
+ }
+ };
+
public void parse(JSONObject data) throws JSONException {
this.start = data.getInt("start");
this.end = (float) data.getDouble("end");
@@ -51,4 +80,21 @@ public void setSumType(SUM_TYPE sumType) {
this.sumType = sumType;
}
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int i) {
+ parcel.writeInt(this.start);
+ parcel.writeFloat(this.end);
+ parcel.writeFloat(this.seconds);
+ parcel.writeLong(this.bytes);
+ parcel.writeDouble(this.bits_per_second);
+ parcel.writeBoolean(this.omitted);
+ parcel.writeBoolean(this.sender);
+ parcel.writeInt(this.sumType.ordinal());
+
+ }
}
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Worker.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ExecuterWorker.java
similarity index 62%
rename from app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Worker.java
rename to app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ExecuterWorker.java
index 1a228178..4e17605b 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3Worker.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ExecuterWorker.java
@@ -6,34 +6,29 @@
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
-package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Worker;
-import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC;
-import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.graphics.Color;
-import android.os.Build;
import android.util.Log;
-import android.widget.TextView;
import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
-import androidx.room.util.StringUtil;
import androidx.work.Data;
import androidx.work.ForegroundInfo;
import androidx.work.WorkManager;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3Input;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3LibLoader;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.R;
-import java.util.Locale;
-public class Iperf3Worker extends Worker {
+public class Iperf3ExecuterWorker extends Worker {
private static final String TAG = "iperf3Worker";
static {
@@ -41,27 +36,21 @@ public class Iperf3Worker extends Worker {
}
private final String[] cmd;
- private final String iperf3WorkerID;
- private final String measurementName;
- private final String timestamp;
- private final int notificationID;
- private final String client;
- private final String protocol;
- private String serverPort;
- private final String ip;
+ private final String uuid;
private final int FOREGROUND_SERVICE_TYPE = FOREGROUND_SERVICE_TYPE_SPECIAL_USE;
-
- public Iperf3Worker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
+ private final int notificationID = 1002;
+ private String ip;
+ private String port;
+ private String protocol;
+ private Iperf3Input.Iperf3Mode mode;
+ public Iperf3ExecuterWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
- cmd = getInputData().getStringArray("commands");
- measurementName = getInputData().getString("measurementName");
- iperf3WorkerID = getInputData().getString("iperf3WorkerID");
- timestamp = getInputData().getString("timestamp");
- notificationID = 100;
- client = getInputData().getString("client");
+ cmd = getInputData().getStringArray("command");
+ uuid = getInputData().getString("uuid");
ip = getInputData().getString("ip");
- serverPort = getInputData().getString("port");
+ port = getInputData().getString("port");
protocol = getInputData().getString("protocol");
+ mode = Iperf3Input.Iperf3Mode.valueOf(getInputData().getString("mode"));
}
@@ -76,7 +65,7 @@ private ForegroundInfo createForegroundInfo(@NonNull String progress) {
PendingIntent intent = WorkManager.getInstance(context)
.createCancelPendingIntent(getId());
Notification notification = new NotificationCompat.Builder(context, id)
- .setContentTitle("iPerf3 "+ client.substring(0, 1).toUpperCase() + client.substring(1).toLowerCase())
+ //.setContentTitle("iPerf3 "+ client.substring(0, 1).toUpperCase() + client.substring(1).toLowerCase())
.setContentText(progress)
.setOngoing(true)
.setColor(Color.WHITE)
@@ -96,10 +85,11 @@ public void onStopped() {
@NonNull
@Override
public Result doWork() {
- if (serverPort == null) serverPort = "5201";
- String progress = String.format("Connected to %s:%s with %s", ip, serverPort, protocol);
- if (client.equals("server")) {
- progress = String.format("Running on %s:%s", ip, serverPort);
+ Log.i(TAG, "doWork: called!");
+ if (port == null) port = "5201";
+ String progress = String.format("Connecting to %s:%s with %s", ip, port, protocol);
+ if (mode.equals(Iperf3Input.Iperf3Mode.SERVER)) {
+ progress = String.format("Running on %s:%s", ip, port);
}
setForegroundAsync(createForegroundInfo(progress));
@@ -111,7 +101,7 @@ public Result doWork() {
Data.Builder output = new Data.Builder()
.putInt("iperf3_result", result)
- .putString("iperf3WorkerID", iperf3WorkerID);
+ .putString("iperf3WorkerID", uuid);
if (result == 0) {
return Result.success(output.build());
}
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3ToLineProtocolWorker.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ToLineProtocolWorker.java
similarity index 95%
rename from app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3ToLineProtocolWorker.java
rename to app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ToLineProtocolWorker.java
index 86cf58fc..0fe6a59c 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3ToLineProtocolWorker.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3ToLineProtocolWorker.java
@@ -6,7 +6,7 @@
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
-package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Worker;
import android.content.Context;
import android.os.Build;
@@ -22,6 +22,12 @@
import com.influxdb.client.domain.WritePrecision;
import com.influxdb.client.write.Point;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3Input;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Iperf3Parser;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Interval;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.Stream;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.TCP.TCP_UL_STREAM;
+import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.UDP.UDP_DL_STREAM;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -34,10 +40,6 @@
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.GlobalVars;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.InfluxDB2x.InfluxdbConnection;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.InfluxDB2x.InfluxdbConnections;
-import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Interval;
-import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.Stream;
-import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.TCP.TCP_UL_STREAM;
-import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.JSON.Interval.Streams.UDP.UDP_DL_STREAM;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SPType;
import de.fraunhofer.fokus.OpenMobileNetworkToolkit.Preferences.SharedPreferencesGrouper;
@@ -57,7 +59,7 @@ public class Iperf3ToLineProtocolWorker extends Worker {
private final String protocol;
private final String iperf3LineProtocolFile;
- private final DeviceInformation di = GlobalVars.getInstance().get_dp().getDeviceInformation();
+ private final DeviceInformation di;
private final boolean rev;
private final boolean biDir;
@@ -68,6 +70,7 @@ public class Iperf3ToLineProtocolWorker extends Worker {
public Iperf3ToLineProtocolWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
rawIperf3file = getInputData().getString("rawIperf3file");
+ di = GlobalVars.getInstance().get_dp().getDeviceInformation();
ip = getInputData().getString("ip");
measurementName = getInputData().getString("measurementName");
@@ -145,7 +148,7 @@ public Result doWork() {
setup();
Data output = new Data.Builder().putBoolean("iperf3_upload", false).build();
- Iperf3Parser iperf3Parser = new Iperf3Parser(rawIperf3file);
+ Iperf3Parser iperf3Parser = new Iperf3Parser(getApplicationContext(), rawIperf3file, new Iperf3Input());
iperf3Parser.parse();
@@ -238,7 +241,7 @@ public Result doWork() {
iperf3Stream = new FileOutputStream(iperf3LineProtocolFile, true);
} catch (FileNotFoundException e) {
Toast.makeText(getApplicationContext(), "logfile not created", Toast.LENGTH_SHORT).show();
- Log.d(TAG,e.toString());
+ e.printStackTrace();
}
if(iperf3Stream == null){
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3UploadWorker.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3UploadWorker.java
similarity index 97%
rename from app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3UploadWorker.java
rename to app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3UploadWorker.java
index b3ff8d43..5f15b1a7 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Iperf3UploadWorker.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/Iperf3/Worker/Iperf3UploadWorker.java
@@ -6,7 +6,7 @@
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
-package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3;
+package de.fraunhofer.fokus.OpenMobileNetworkToolkit.Iperf3.Worker;
import android.content.Context;
import android.util.Log;
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java
index 69b96766..bd41bef7 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/LoggingService.java
@@ -296,6 +296,10 @@ public void onDestroy() {
private ArrayList getPoints() {
long time = System.currentTimeMillis();
+ if(dp == null) {
+ Log.e(TAG, "getPoints: Dataprovider is null!");
+ return new ArrayList<>();
+ }
Map tags_map = dp.getTagsMap();
ArrayList logPoints = new ArrayList<>();
diff --git a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java
index 6b48c36d..eb1ae1f7 100644
--- a/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java
+++ b/app/src/main/java/de/fraunhofer/fokus/OpenMobileNetworkToolkit/MainActivity.java
@@ -47,6 +47,7 @@
import androidx.navigation.fragment.NavHostFragment;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
+import androidx.work.WorkManager;
import java.security.MessageDigest;
import java.util.ArrayList;
@@ -105,7 +106,7 @@ protected void onCreate(Bundle savedInstanceState) {
spg = SharedPreferencesGrouper.getInstance(getApplicationContext());
pm = getPackageManager();
feature_telephony = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
-
+ WorkManager.getInstance(context).cancelAllWork();
// populate global vars we use in other parts of the app.
gv.setPm(pm);
gv.setPermission_phone_state(ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED);
@@ -478,4 +479,5 @@ public boolean onPreferenceStartFragment(@NonNull PreferenceFragmentCompat calle
}
return true;
}
+
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/dashed_outline.xml b/app/src/main/res/drawable/dashed_outline.xml
new file mode 100644
index 00000000..9e66ce6e
--- /dev/null
+++ b/app/src/main/res/drawable/dashed_outline.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/grid_shape.xml b/app/src/main/res/drawable/grid_shape.xml
new file mode 100644
index 00000000..0406b401
--- /dev/null
+++ b/app/src/main/res/drawable/grid_shape.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_iperf3_card.xml b/app/src/main/res/layout/fragment_iperf3_card.xml
new file mode 100644
index 00000000..983fca3f
--- /dev/null
+++ b/app/src/main/res/layout/fragment_iperf3_card.xml
@@ -0,0 +1,236 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_iperf3_card_add.xml b/app/src/main/res/layout/fragment_iperf3_card_add.xml
new file mode 100644
index 00000000..447d8699
--- /dev/null
+++ b/app/src/main/res/layout/fragment_iperf3_card_add.xml
@@ -0,0 +1,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_iperf3_input.xml b/app/src/main/res/layout/fragment_iperf3_input.xml
index 61fa0ff7..ad4b1185 100644
--- a/app/src/main/res/layout/fragment_iperf3_input.xml
+++ b/app/src/main/res/layout/fragment_iperf3_input.xml
@@ -7,287 +7,20 @@
~ SPDX-License-Identifier: BSD-3-Clause-Clear
-->
-
+ android:orientation="vertical">
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/fragment_iperf3_list.xml b/app/src/main/res/layout/fragment_iperf3_list.xml
index 14c2ea82..d06f8d0e 100644
--- a/app/src/main/res/layout/fragment_iperf3_list.xml
+++ b/app/src/main/res/layout/fragment_iperf3_list.xml
@@ -15,7 +15,7 @@
android:exported="true"
android:background="?android:attr/selectableItemBackground"
android:id="@+id/iperf3_list_fragment"
- tools:context=".Iperf3.Iperf3ListFragment" >
+ tools:context=".Iperf3.Fragments.Output.Iperf3ListFragment" >
diff --git a/app/src/main/res/layout/grid_item_card.xml b/app/src/main/res/layout/grid_item_card.xml
new file mode 100644
index 00000000..79acbb54
--- /dev/null
+++ b/app/src/main/res/layout/grid_item_card.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml
index 64ecf6ab..95cf8f37 100644
--- a/app/src/main/res/navigation/nav_graph.xml
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -86,7 +86,7 @@
@@ -99,7 +99,7 @@
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e429caf8..555241af 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -32,15 +32,15 @@
I need your permission
APN Settings
Slicing
- -F / Logfile Name
- -c / IP
+ -F
+ -c
Client
- -p / Port
- -b / Bandwidth
+ -p
+ -b
Reverse
- -t / Duration
- -i / Interval
- -n / Bytes
+ -t
+ -i
+ -n
BiDir
JSON
one-off
@@ -111,7 +111,7 @@
Cleared.
Set up managed profile
Preferential Network Service
- -P / Parallel streams
+ -P
Settings
InfluxDB
Special Codes
@@ -158,6 +158,8 @@
Do you want to clear all Configuartions?
Yes
No
+ valueCardView
+
N/A
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index ce3edeea..879f3462 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -1,20 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file