diff --git a/Main/chameleon-vision.iml b/Main/chameleon-vision.iml
index d285b15a4..f29e8915e 100644
--- a/Main/chameleon-vision.iml
+++ b/Main/chameleon-vision.iml
@@ -10,23 +10,13 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -66,13 +56,13 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/Main/src/main/java/com/chameleonvision/Main.java b/Main/src/main/java/com/chameleonvision/Main.java
index e380eec0a..4b47c7db3 100644
--- a/Main/src/main/java/com/chameleonvision/Main.java
+++ b/Main/src/main/java/com/chameleonvision/Main.java
@@ -1,16 +1,18 @@
package com.chameleonvision;
+import com.chameleonvision.network.NetworkManager;
import com.chameleonvision.settings.Platform;
import com.chameleonvision.settings.SettingsManager;
-import com.chameleonvision.settings.network.NetworkManager;
import com.chameleonvision.util.Utilities;
import com.chameleonvision.vision.camera.CameraManager;
import com.chameleonvision.web.Server;
import edu.wpi.cscore.CameraServerCvJNI;
import edu.wpi.cscore.CameraServerJNI;
+import edu.wpi.first.networktables.LogMessage;
import edu.wpi.first.networktables.NetworkTableInstance;
import java.io.IOException;
+import java.util.function.Consumer;
public class Main {
@@ -18,14 +20,31 @@ public class Main {
private static final String NT_SERVERMODE_KEY = "--nt-servermode"; // no args for this setting
private static final String NT_CLIENTMODESERVER_KEY = "--nt-client-server"; // expects String representing an IP address (hostnames will be rejected!)
private static final String NETWORK_MANAGE_KEY = "--unmanage-network"; // no args for this setting
+ private static final String IGNORE_ROOT = "--ignore-root"; // no args for this setting
private static final int DEFAULT_PORT = 8888;
private static int webserverPort = DEFAULT_PORT;
private static boolean ntServerMode = false;
private static boolean manageNetwork = true;
+ private static boolean ignoreRoot = false;
private static String ntClientModeServer = null;
+ private static class NTLogger implements Consumer {
+
+ private boolean hasReportedConnectionFailure = false;
+
+ @Override
+ public void accept(LogMessage logMessage) {
+ if (!hasReportedConnectionFailure && logMessage.message.contains("timed out")) {
+ System.err.println("NT Connection has failed!");
+ hasReportedConnectionFailure = true;
+ }
+ }
+ }
+
+ public static final Platform CurrentPlatform = Platform.getCurrentPlatform();
+
private static void handleArgs(String[] args) {
for (int i = 0; i < args.length; i++) {
var key = args[i].toLowerCase();
@@ -44,6 +63,7 @@ public class Main {
break;
case NT_SERVERMODE_KEY:
case NETWORK_MANAGE_KEY:
+ case IGNORE_ROOT:
// nothing
}
@@ -78,6 +98,8 @@ public class Main {
case NETWORK_MANAGE_KEY:
manageNetwork = false;
break;
+ case IGNORE_ROOT:
+ ignoreRoot = true;
}
}
}
@@ -85,23 +107,36 @@ public class Main {
public static void main(String[] args) {
handleArgs(args);
+ if (!CurrentPlatform.isRoot()) {
+ if (ignoreRoot) {
+ // TODO: should we do this?
+ // manageNetwork = false;
+ System.out.println("Ignoring root, network will not be managed!");
+ } else {
+ System.err.println("This program must be run as root!");
+ return;
+ }
+ }
+
// Attempt to load the JNI Libraries
try {
CameraServerJNI.forceLoad();
CameraServerCvJNI.forceLoad();
} catch (IOException e) {
- var errorStr = Platform.getCurrentPlatform().equals(Platform.UNSUPPORTED) ? "Unsupported platform!" : "Failed to load JNI Libraries!";
+ var errorStr = CurrentPlatform.equals(Platform.UNSUPPORTED) ? "Unsupported platform!" : "Failed to load JNI Libraries!";
throw new RuntimeException(errorStr);
}
if (CameraManager.initializeCameras()) {
- SettingsManager.initialize(manageNetwork);
+ SettingsManager.initialize();
+ NetworkManager.initialize(manageNetwork);
CameraManager.initializeThreads();
if (ntServerMode) {
System.out.println("Starting NT Server");
NetworkTableInstance.getDefault().startServer();
} else {
+ NetworkTableInstance.getDefault().addLogger(new NTLogger(), 0, 255); // to hide error messages
if (ntClientModeServer != null) {
NetworkTableInstance.getDefault().startClient(ntClientModeServer);
} else {
diff --git a/Main/src/main/java/com/chameleonvision/network/LinuxNetworking.java b/Main/src/main/java/com/chameleonvision/network/LinuxNetworking.java
new file mode 100644
index 000000000..e22722324
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/network/LinuxNetworking.java
@@ -0,0 +1,99 @@
+package com.chameleonvision.network;
+
+import com.chameleonvision.settings.NetworkSettings;
+import com.chameleonvision.settings.SettingsManager;
+import com.chameleonvision.util.ShellExec;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class LinuxNetworking extends SysNetworking {
+
+ private ShellExec shell = new ShellExec(true, true);
+
+ @Override
+ public boolean setDHCP() {
+ var ifaceName = networkInterface.name;
+ var ethResetCmd = String.format("ifconfig %s 0.0.0.0 0.0.0.0", ifaceName);
+ var dhclientCmd = String.format("dhclient %s", ifaceName);
+
+
+ // ifconfig eth0 0.0.0.0 0.0.0.0
+ try {
+ int retCode = shell.execute("ifconfig", null, true, ifaceName, "0.0.0.0", "0.0.0.0");
+ while (!shell.isOutputCompleted() && !shell.isErrorCompleted()) {}
+ var out = shell.getOutput();
+ var err = shell.getError();
+ if (retCode != 0) return false;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ try {
+ int retCode = shell.execute("dhclient", null, true, ifaceName);
+ while (!shell.isOutputCompleted() && !shell.isErrorCompleted()) {}
+ var out = shell.getOutput();
+ var err = shell.getError();
+ if (retCode != 0) return false;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean setHostname(String newHostname) {
+ var cmdString = String.format("hostnamectl set-hostname %s", newHostname);
+
+ try {
+ var process = Runtime.getRuntime().exec(cmdString);
+ var returnCode = shell.execute("hostnamectl", null, true, "set-hostname", newHostname);
+ return returnCode == 0;
+ } catch(Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ @Override
+ public boolean setStatic(String ipAddress, String netmask, String gateway, String broadcast) {
+ try {
+ int clearRetCode = shell.execute("ip addr flush dev", null, true, networkInterface.name);
+ int setIPRetCode = shell.execute(String.format("ip addr add %s/%s broadcast %s dev %s", ipAddress, netmask, broadcast, networkInterface.name), null, true);
+ int setGatewayRetCode = shell.execute(String.format("ip route replace default via %s dev %s", gateway, networkInterface.name), null, false);
+ return clearRetCode == 0 && setIPRetCode == 0 && setGatewayRetCode == 0;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ @Override
+ public List getNetworkInterfaces() throws SocketException {
+ List netInterfaces;
+ try {
+ netInterfaces = Collections.list(java.net.NetworkInterface.getNetworkInterfaces());
+ } catch (SocketException e) {
+ return null;
+ }
+
+ List goodInterfaces = new ArrayList<>();
+
+ for (var netInterface : netInterfaces) {
+ if (netInterface.getDisplayName().contains("lo")) continue;
+ if (!netInterface.isUp()) continue;
+ goodInterfaces.add(netInterface);
+ }
+ return goodInterfaces;
+
+ }
+}
diff --git a/Main/src/main/java/com/chameleonvision/settings/network/NetworkIPMode.java b/Main/src/main/java/com/chameleonvision/network/NetworkIPMode.java
similarity index 54%
rename from Main/src/main/java/com/chameleonvision/settings/network/NetworkIPMode.java
rename to Main/src/main/java/com/chameleonvision/network/NetworkIPMode.java
index b3e28ee36..ec5a376d3 100644
--- a/Main/src/main/java/com/chameleonvision/settings/network/NetworkIPMode.java
+++ b/Main/src/main/java/com/chameleonvision/network/NetworkIPMode.java
@@ -1,4 +1,4 @@
-package com.chameleonvision.settings.network;
+package com.chameleonvision.network;
public enum NetworkIPMode {
DHCP,
diff --git a/Main/src/main/java/com/chameleonvision/network/NetworkInterface.java b/Main/src/main/java/com/chameleonvision/network/NetworkInterface.java
new file mode 100644
index 000000000..75b5f7224
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/network/NetworkInterface.java
@@ -0,0 +1,57 @@
+package com.chameleonvision.network;
+
+import com.chameleonvision.settings.GeneralSettings;
+
+import java.net.InetAddress;
+import java.net.InterfaceAddress;
+
+public class NetworkInterface {
+ public final String name;
+ public final String displayName;
+ public final String IPAddress;
+ public final String Netmask;
+ public final String Gateway;
+ public final String Broadcast;
+
+ public NetworkInterface(java.net.NetworkInterface inetface, InterfaceAddress ifaceAddress) {
+ name = inetface.getName();
+ displayName = inetface.getDisplayName();
+
+ var inetAddress = ifaceAddress.getAddress();
+ IPAddress = inetAddress.getHostAddress();
+ Netmask = getIPv4LocalNetMask(ifaceAddress);
+
+ // TODO: hack to "get" gateway, this is gross and bad, pls fix
+ var splitIPAddr = IPAddress.split("\\.");
+ splitIPAddr[3] = "1";
+ Gateway = String.join(".", splitIPAddr);
+ splitIPAddr[3] = "255";
+ Broadcast = String.join(".", splitIPAddr);
+ }
+
+ private static String getIPv4LocalNetMask(InterfaceAddress interfaceAddress) {
+ var netPrefix = interfaceAddress.getNetworkPrefixLength();
+ try {
+ // Since this is for IPv4, it's 32 bits, so set the sign value of
+ // the int to "negative"...
+ int shiftby = (1<<31);
+ // For the number of bits of the prefix -1 (we already set the sign bit)
+ for (int i = netPrefix - 1; i > 0; i--) {
+ // Shift the sign right... Java makes the sign bit sticky on a shift...
+ // So no need to "set it back up"...
+ shiftby = (shiftby >> 1);
+ }
+ // Transform the resulting value in xxx.xxx.xxx.xxx format, like if
+ /// it was a standard address...
+ String maskString = ((shiftby >> 24) & 255) + "." + ((shiftby >> 16) & 255) + "." + ((shiftby >> 8) & 255) + "." + (shiftby & 255);
+ // Return the address thus created...
+ return maskString;
+// return InetAddress.getByName(maskString);
+ }
+ catch(Exception e) {
+ e.printStackTrace();
+ }
+ // Something went wrong here...
+ return null;
+ }
+}
diff --git a/Main/src/main/java/com/chameleonvision/network/NetworkManager.java b/Main/src/main/java/com/chameleonvision/network/NetworkManager.java
new file mode 100644
index 000000000..a287e98c1
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/network/NetworkManager.java
@@ -0,0 +1,122 @@
+package com.chameleonvision.network;
+
+
+import com.chameleonvision.settings.NetworkSettings;
+import com.chameleonvision.settings.Platform;
+import com.chameleonvision.settings.SettingsManager;
+
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class NetworkManager {
+ private NetworkManager() {}
+
+ protected static SysNetworking networking;
+ protected static NetworkInterface botInterface = null;
+ private static boolean isManaged = false;
+
+ public static void initialize(boolean manage) {
+ isManaged = manage;
+ if (!isManaged) {
+ return;
+ }
+
+ Platform platform = Platform.getCurrentPlatform();
+
+ if (platform.isLinux()) {
+ networking = new LinuxNetworking();
+ } else if (platform.isWindows()) {
+// networking = new WindowsNetworking();
+ System.out.println("Windows networking is not yet supported. Running unmanaged.");
+ return;
+ }
+
+ List interfaces = new ArrayList<>();
+ List goodInterfaces = new ArrayList<>();
+
+ try {
+ interfaces = networking.getNetworkInterfaces();
+ } catch (SocketException e) {
+ e.printStackTrace();
+ }
+
+ var teamBytes = NetworkSettings.GetTeamNumberIPBytes(SettingsManager.GeneralSettings.team_number);
+
+ if (interfaces.size() > 0) {
+ for (var inetface : interfaces) {
+ for (var inetfaceAddr : inetface.getInterfaceAddresses()) {
+ var rawAddr = inetfaceAddr.getAddress().getAddress();
+ if (rawAddr.length > 4) continue;
+ if (rawAddr[1] == teamBytes[0] && rawAddr[2] == teamBytes[1]) {
+ goodInterfaces.add(new NetworkInterface(inetface, inetfaceAddr));
+ }
+ }
+ }
+
+ if (goodInterfaces.size() == 0) {
+ isManaged = false;
+ System.err.println("No valid network interfaces found! Staying unmanaged.");
+ return;
+ }
+
+ botInterface = goodInterfaces.get(0);
+ networking.setNetworkInterface(botInterface);
+ } else {
+ isManaged = false;
+ System.err.println("No valid network interfaces found! Staying unmanaged.");
+ return;
+ }
+
+ if(!loadFromGeneralSettings()) {
+ isManaged = false;
+ System.err.println("Failed to load network settings. Staying unmanaged!");
+ }
+ }
+
+ private static boolean loadFromGeneralSettings() {
+ if (!isManaged) {
+ return true;
+ }
+
+ var genSettings = SettingsManager.GeneralSettings;
+ boolean isStatic = genSettings.connection_type.toLowerCase().equals("Static");
+
+ if (isStatic) {
+ var splitIPAddr = genSettings.ip.split("\\.");
+ splitIPAddr[3] = "255";
+ var broadcast = String.join(".", splitIPAddr);
+ if (!setStatic(genSettings.ip, genSettings.netmask, genSettings.gateway, broadcast)) {
+ return false;
+ }
+ } else {
+ if (!setDHCP()) {
+ return false;
+ }
+ }
+
+ return setHostname(genSettings.hostname);
+ }
+
+ private static boolean setDHCP() {
+ if (!isManaged) {
+ return true;
+ }
+ return networking.setDHCP();
+ }
+
+ private static boolean setStatic(String ipAddress, String netmask, String gateway, String broadcast) {
+ if (!isManaged) {
+ return true;
+ }
+ return networking.setStatic(ipAddress, netmask, gateway, broadcast);
+ }
+
+ private static boolean setHostname(String hostname) {
+ if (!isManaged) {
+ return true;
+ }
+ return networking.setHostname(hostname);
+ }
+}
diff --git a/Main/src/main/java/com/chameleonvision/network/SysNetworking.java b/Main/src/main/java/com/chameleonvision/network/SysNetworking.java
new file mode 100644
index 000000000..91684e775
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/network/SysNetworking.java
@@ -0,0 +1,37 @@
+package com.chameleonvision.network;
+
+import com.chameleonvision.util.ShellExec;
+
+import java.io.IOException;
+import java.net.SocketException;
+import java.util.List;
+import java.util.Scanner;
+
+public abstract class SysNetworking {
+
+ NetworkInterface networkInterface;
+ ShellExec shell = new ShellExec(true, true);
+
+ public String getHostname() {
+ try {
+ var retCode = shell.execute("hostname", null, true);
+ if (retCode == 0) {
+ while(!shell.isOutputCompleted()) {}
+ return shell.getOutput();
+ } else {
+ return null;
+ }
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ public void setNetworkInterface(NetworkInterface networkInterface) {
+ this.networkInterface = networkInterface;
+ }
+ public abstract boolean setDHCP();
+ public abstract boolean setHostname(String hostname);
+ public abstract boolean setStatic(String ipAddress, String netmask, String gateway, String broadcast);
+ public abstract List getNetworkInterfaces() throws SocketException;
+
+}
diff --git a/Main/src/main/java/com/chameleonvision/network/WindowsNetworking.java b/Main/src/main/java/com/chameleonvision/network/WindowsNetworking.java
new file mode 100644
index 000000000..d6ccd829b
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/network/WindowsNetworking.java
@@ -0,0 +1,57 @@
+package com.chameleonvision.network;
+
+import com.chameleonvision.settings.NetworkSettings;
+import com.chameleonvision.settings.SettingsManager;
+
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class WindowsNetworking extends SysNetworking {
+
+ @Override
+ public boolean setDHCP() {
+ return false;
+ }
+
+ @Override
+ public boolean setHostname(String newHostname) {
+ var currentHostname = getHostname();
+
+ if (getHostname() == null) {
+ return false;
+ }
+
+ String command = String.format("wmic computersystem where name=\"%s\" call rename name=\"%s\"", currentHostname, newHostname);
+
+ try {
+ var process = Runtime.getRuntime().exec(command);
+ var returnCode = process.waitFor();
+ return returnCode == 0;
+ } catch(Exception e) {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean setStatic(String ipAddress, String netmask, String gateway, String broadcast) {
+ return false;
+ }
+
+ @Override
+ public List getNetworkInterfaces() throws SocketException {
+ var netInterfaces = Collections.list(java.net.NetworkInterface.getNetworkInterfaces());
+
+ List goodInterfaces = new ArrayList<>();
+
+ for (var netInterface : netInterfaces) {
+ if (netInterface.getDisplayName().toLowerCase().contains("bluetooth")) continue;
+ if (netInterface.getDisplayName().toLowerCase().contains("virtual")) continue;
+ if (netInterface.getDisplayName().toLowerCase().contains("loopback")) continue;
+ if (!netInterface.isUp()) continue;
+ goodInterfaces.add(netInterface);
+ }
+ return goodInterfaces;
+ }
+}
diff --git a/Main/src/main/java/com/chameleonvision/settings/Platform.java b/Main/src/main/java/com/chameleonvision/settings/Platform.java
index 12acdd962..1709a6ebd 100644
--- a/Main/src/main/java/com/chameleonvision/settings/Platform.java
+++ b/Main/src/main/java/com/chameleonvision/settings/Platform.java
@@ -1,10 +1,14 @@
package com.chameleonvision.settings;
+import com.chameleonvision.util.ShellExec;
+
+import java.io.IOException;
+
public enum Platform {
WINDOWS_64("Windows x64"),
LINUX_64("Linux x64"),
LINUX_RASPBIAN("Linux Raspbian"),
- LINUX_AARCH64("Linux ARM 64bit"),
+ LINUX_AARCH64("Linux For Tegra"),
MACOS_64("Mac OS x64"),
UNSUPPORTED("Unsupported Platform");
@@ -26,6 +30,29 @@ public enum Platform {
return this == MACOS_64;
}
+ private static ShellExec shell = new ShellExec(true, false);
+
+ public boolean isRoot() {
+ if (isLinux() || isMac()) {
+ try {
+ shell.execute("id", null, true, "-u");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ while (!shell.isOutputCompleted()) {}
+ if (shell.getExitCode() == 0) {
+ var out = shell.getOutput();
+ out = out.split("\n")[0];
+ return out.equals("0");
+ }
+ } else if (isWindows()) {
+ return true;
+ } else {
+ return true;
+ }
+ return false;
+ }
+
public static Platform getCurrentPlatform() {
var osName = System.getProperty("os.name");
var osArch = System.getProperty("os.arch");
diff --git a/Main/src/main/java/com/chameleonvision/settings/SettingsManager.java b/Main/src/main/java/com/chameleonvision/settings/SettingsManager.java
index 1fbaf09d9..6a2a3c310 100644
--- a/Main/src/main/java/com/chameleonvision/settings/SettingsManager.java
+++ b/Main/src/main/java/com/chameleonvision/settings/SettingsManager.java
@@ -1,6 +1,6 @@
package com.chameleonvision.settings;
-import com.chameleonvision.settings.network.NetworkManager;
+import com.chameleonvision.network.NetworkManager;
import com.chameleonvision.util.FileHelper;
import com.chameleonvision.vision.camera.CameraManager;
import com.google.gson.Gson;
@@ -19,10 +19,10 @@ public class SettingsManager {
private SettingsManager() {}
- public static void initialize(boolean manageNetwork) {
+ public static void initialize() {
initGeneralSettings();
- if (manageNetwork) {
- NetworkManager.init();
+// if (manageNetwork) {
+
// NetworkSettings netSettings = new NetworkSettings();
// netSettings.hostname = GeneralSettings.hostname;
// netSettings.gateway = GeneralSettings.gateway;
@@ -30,7 +30,7 @@ public class SettingsManager {
// netSettings.connectionType = GeneralSettings.connection_type;
// netSettings.ip = GeneralSettings.ip;
// netSettings.run();
- }
+// }
var allCameras = CameraManager.getAllCamerasByName();
if (!allCameras.containsKey(GeneralSettings.curr_camera) && allCameras.size() > 0) {
var cam = allCameras.entrySet().stream().findFirst().get().getValue();
diff --git a/Main/src/main/java/com/chameleonvision/settings/network/INetworking.java b/Main/src/main/java/com/chameleonvision/settings/network/INetworking.java
deleted file mode 100644
index e34e736d3..000000000
--- a/Main/src/main/java/com/chameleonvision/settings/network/INetworking.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.chameleonvision.settings.network;
-
-import java.net.SocketException;
-import java.util.List;
-
-public interface INetworking {
- String getHostname();
- NetworkIPMode getIPMode();
- boolean setDHCP();
- boolean setHostname(String hostname);
- boolean setStatic(String ipAddress, String netmask, String gateway);
- List getNetworkInterfaces() throws SocketException;
-
-}
diff --git a/Main/src/main/java/com/chameleonvision/settings/network/LinuxNetworking.java b/Main/src/main/java/com/chameleonvision/settings/network/LinuxNetworking.java
deleted file mode 100644
index 9b664826b..000000000
--- a/Main/src/main/java/com/chameleonvision/settings/network/LinuxNetworking.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.chameleonvision.settings.network;
-
-import java.net.SocketException;
-import java.util.List;
-
-public class LinuxNetworking implements INetworking {
-
- @Override
- public String getHostname() {
- return null;
- }
-
- @Override
- public NetworkIPMode getIPMode() {
- return null;
- }
-
- @Override
- public boolean setDHCP() {
- return false;
- }
-
- @Override
- public boolean setHostname(String hostname) {
- return false;
- }
-
- @Override
- public boolean setStatic(String ipAddress, String netmask, String gateway) {
- return false;
- }
-
- @Override
- public List getNetworkInterfaces() throws SocketException {
- return null;
- }
-}
diff --git a/Main/src/main/java/com/chameleonvision/settings/network/NetworkInterface.java b/Main/src/main/java/com/chameleonvision/settings/network/NetworkInterface.java
deleted file mode 100644
index 57e7adbbe..000000000
--- a/Main/src/main/java/com/chameleonvision/settings/network/NetworkInterface.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.chameleonvision.settings.network;
-
-import com.chameleonvision.settings.NetworkSettings;
-import com.chameleonvision.settings.SettingsManager;
-
-import java.net.InetAddress;
-import java.util.Collections;
-
-public class NetworkInterface {
- public final String name;
- public final String displayName;
-// public NetworkIPMode IPMode;
-// public String IPAddress;
-// public String Netmask;
-// public String Gateway;
-
- public NetworkInterface(java.net.NetworkInterface inetface) {
-
- name = inetface.getName();
- displayName = inetface.getDisplayName();
-
- }
-}
diff --git a/Main/src/main/java/com/chameleonvision/settings/network/NetworkManager.java b/Main/src/main/java/com/chameleonvision/settings/network/NetworkManager.java
deleted file mode 100644
index 08bea3db9..000000000
--- a/Main/src/main/java/com/chameleonvision/settings/network/NetworkManager.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.chameleonvision.settings.network;
-
-
-import com.chameleonvision.settings.Platform;
-
-import java.net.SocketException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class NetworkManager {
- private NetworkManager() {}
-
- private static INetworking networking;
-
- public static void init() {
- Platform platform = Platform.getCurrentPlatform();
-
- if (platform.isLinux()) {
- networking = new LinuxNetworking();
- } else if (platform.isWindows()) {
- networking = new WindowsNetworking();
- }
-
- List interfaces = new ArrayList<>();
-
- try {
- interfaces = networking.getNetworkInterfaces();
- } catch (SocketException e) {
- e.printStackTrace();
- }
-
- if (interfaces != null) {
- for (var inetface : interfaces) {
- if (inetface.displayName.toLowerCase().contains("asus")) {
-// networking.setHostname("BIGRIG");
- }
- }
- }
- }
-}
diff --git a/Main/src/main/java/com/chameleonvision/settings/network/WindowsNetworking.java b/Main/src/main/java/com/chameleonvision/settings/network/WindowsNetworking.java
deleted file mode 100644
index 9dfd9df2c..000000000
--- a/Main/src/main/java/com/chameleonvision/settings/network/WindowsNetworking.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.chameleonvision.settings.network;
-
-import com.chameleonvision.settings.NetworkSettings;
-import com.chameleonvision.settings.SettingsManager;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.net.InetAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public class WindowsNetworking implements INetworking {
-
- @Override
- public String getHostname() {
- try {
- InetAddress localhost = InetAddress.getLocalHost();
- return localhost.getHostName().split("/")[0];
- } catch (UnknownHostException e) {
- return null;
- }
- }
-
- @Override
- public NetworkIPMode getIPMode() {
- return NetworkIPMode.UNKNOWN;
- }
-
- @Override
- public boolean setDHCP() {
- return false;
- }
-
- @Override
- public boolean setHostname(String newHostname) {
- var currentHostname = getHostname();
-
- if (getHostname() == null) {
- return false;
- }
-
- String command = String.format("wmic computersystem where name=\"%s\" call rename name=\"%s\"", currentHostname, newHostname);
-
- try {
- var process = Runtime.getRuntime().exec(command);
- var returnCode = process.waitFor();
- return returnCode == 0;
- } catch(Exception e) {
- return false;
- }
- }
-
- @Override
- public boolean setStatic(String ipAddress, String netmask, String gateway) {
- return false;
- }
-
- @Override
- public List getNetworkInterfaces() throws SocketException {
- var netInterfaces = Collections.list(java.net.NetworkInterface.getNetworkInterfaces());
-
- List goodInterfaces = new ArrayList<>();
-
- var teamBytes = NetworkSettings.GetTeamNumberIPBytes(SettingsManager.GeneralSettings.team_number);
-
- for (var inetface : netInterfaces) {
- if (inetface.getDisplayName().toLowerCase().contains("bluetooth")) continue;
- if (inetface.getDisplayName().toLowerCase().contains("virtual")) continue;
- if (inetface.getDisplayName().toLowerCase().contains("loopback")) continue;
- if (!inetface.isUp()) continue;
- for (var inetAddr : Collections.list(inetface.getInetAddresses())) {
- var rawAddr = inetAddr.getAddress();
- if (rawAddr[1] == teamBytes[0] && rawAddr[2] == teamBytes[1]) {
- goodInterfaces.add(new NetworkInterface(inetface));
- }
- }
- }
- return goodInterfaces;
- }
-}
diff --git a/Main/src/main/java/com/chameleonvision/Handler/MathHandler.java b/Main/src/main/java/com/chameleonvision/util/MathHandler.java
similarity index 84%
rename from Main/src/main/java/com/chameleonvision/Handler/MathHandler.java
rename to Main/src/main/java/com/chameleonvision/util/MathHandler.java
index 40971fffc..651c84da9 100644
--- a/Main/src/main/java/com/chameleonvision/Handler/MathHandler.java
+++ b/Main/src/main/java/com/chameleonvision/util/MathHandler.java
@@ -1,15 +1,20 @@
-package com.chameleonvision.Handler;
+package com.chameleonvision.util;
+
import java.lang.Math;
+
public class MathHandler {
- MathHandler(){}
+ MathHandler() {}
+
public static double sigmoid(double x){
double bias = 0;
double a = 5;
double b = -0.05;
double k = 200;
+
if (x < 50){
bias = -1.338;
}
+
return ((k / (1 + Math.pow(Math.E,(a + (b * x))))) + bias);
}
}
diff --git a/Main/src/main/java/com/chameleonvision/util/ShellExec.java b/Main/src/main/java/com/chameleonvision/util/ShellExec.java
new file mode 100644
index 000000000..65a7c4f47
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/util/ShellExec.java
@@ -0,0 +1,141 @@
+package com.chameleonvision.util;
+
+import java.io.*;
+
+/**
+ * Execute external process and optionally read output buffer.
+ */
+public class ShellExec {
+ private int exitCode;
+ private boolean readOutput, readError;
+ private StreamGobbler errorGobbler, outputGobbler;
+
+ public ShellExec() {
+ this(false, false);
+ }
+
+ public ShellExec(boolean readOutput, boolean readError) {
+ this.readOutput = readOutput;
+ this.readError = readError;
+ }
+
+ /**
+ * Execute a command.
+ * @param command command ("c:/some/folder/script.bat" or "some/folder/script.sh")
+ * @param workdir working directory or NULL to use command folder
+ * @param wait wait for process to end
+ * @param args 0..n command line arguments
+ * @return process exit code
+ */
+ public int execute(String command, String workdir, boolean wait, String...args) throws IOException {
+ String[] cmdArr;
+ if (args != null && args.length > 0) {
+ cmdArr = new String[1+args.length];
+ cmdArr[0] = command;
+ System.arraycopy(args, 0, cmdArr, 1, args.length);
+ } else {
+ cmdArr = new String[] { command };
+ }
+
+ ProcessBuilder pb = new ProcessBuilder(cmdArr);
+ File workingDir = (workdir==null ? new File(command).getParentFile() : new File(workdir) );
+ pb.directory(workingDir);
+
+ Process process = pb.start();
+
+ // Consume streams, older jvm's had a memory leak if streams were not read,
+ // some other jvm+OS combinations may block unless streams are consumed.
+ errorGobbler = new StreamGobbler(process.getErrorStream(), readError);
+ outputGobbler = new StreamGobbler(process.getInputStream(), readOutput);
+ errorGobbler.start();
+ outputGobbler.start();
+
+ exitCode = 0;
+ if (wait) {
+ try {
+ process.waitFor();
+ exitCode = process.exitValue();
+ } catch (InterruptedException ignored) { }
+ }
+ return exitCode;
+ }
+
+ public int getExitCode() {
+ return exitCode;
+ }
+
+ public boolean isOutputCompleted() {
+ return (outputGobbler != null && outputGobbler.isCompleted());
+ }
+
+ public boolean isErrorCompleted() {
+ return (errorGobbler != null && errorGobbler.isCompleted());
+ }
+
+ public String getOutput() {
+ return (outputGobbler != null ? outputGobbler.getOutput() : null);
+ }
+
+ public String getError() {
+ return (errorGobbler != null ? errorGobbler.getOutput() : null);
+ }
+
+//********************************************
+//********************************************
+
+ /**
+ * StreamGobbler reads inputstream to "gobble" it.
+ * This is used by Executor class when running
+ * a commandline applications. Gobblers must read/purge
+ * INSTR and ERRSTR process streams.
+ * http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4
+ */
+ @SuppressWarnings("WeakerAccess")
+ private class StreamGobbler extends Thread {
+ private InputStream is;
+ private StringBuilder output;
+ private volatile boolean completed; // mark volatile to guarantee a thread safety
+
+ public StreamGobbler(InputStream is, boolean readStream) {
+ this.is = is;
+ this.output = (readStream ? new StringBuilder(256) : null);
+ }
+
+ public void run() {
+ completed = false;
+ try {
+ String NL = System.getProperty("line.separator", "\r\n");
+
+ InputStreamReader isr = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(isr);
+ String line;
+ while ( (line = br.readLine()) != null) {
+ if (output != null)
+ output.append(line).append(NL);
+ }
+ } catch (IOException ex) {
+ // ex.printStackTrace();
+ }
+ completed = true;
+ }
+
+ /**
+ * Get inputstream buffer or null if stream
+ * was not consumed.
+ * @return
+ */
+ public String getOutput() {
+ return (output != null ? output.toString() : null);
+ }
+
+ /**
+ * Is input stream completed.
+ * @return
+ */
+ public boolean isCompleted() {
+ return completed;
+ }
+
+ }
+
+}
diff --git a/Main/src/main/java/com/chameleonvision/vision/process/CVProcess.java b/Main/src/main/java/com/chameleonvision/vision/process/CVProcess.java
index d701efbf5..80063f605 100644
--- a/Main/src/main/java/com/chameleonvision/vision/process/CVProcess.java
+++ b/Main/src/main/java/com/chameleonvision/vision/process/CVProcess.java
@@ -1,7 +1,7 @@
package com.chameleonvision.vision.process;
import com.chameleonvision.vision.camera.CameraValues;
-import com.chameleonvision.Handler.MathHandler;
+import com.chameleonvision.util.MathHandler;
import org.apache.commons.math3.util.FastMath;
import org.jetbrains.annotations.NotNull;
import org.opencv.core.*;