diff --git a/chameleon-server/chameleon-vision.iml b/chameleon-server/chameleon-vision.iml
index e863282a1..445efaa82 100644
--- a/chameleon-server/chameleon-vision.iml
+++ b/chameleon-server/chameleon-vision.iml
@@ -11,6 +11,7 @@
+
@@ -36,6 +37,7 @@
+
diff --git a/chameleon-server/pom.xml b/chameleon-server/pom.xml
index d02cdfc4e..bdc1ad0a9 100644
--- a/chameleon-server/pom.xml
+++ b/chameleon-server/pom.xml
@@ -86,6 +86,11 @@
commons-math3
3.6.1
+
+ commons-io
+ commons-io
+ RELEASE
+
org.msgpack
msgpack-core
diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/LinuxNetworking.java b/chameleon-server/src/main/java/com/chameleonvision/network/LinuxNetworking.java
index 42998a9a0..2794f0c9a 100644
--- a/chameleon-server/src/main/java/com/chameleonvision/network/LinuxNetworking.java
+++ b/chameleon-server/src/main/java/com/chameleonvision/network/LinuxNetworking.java
@@ -1,73 +1,102 @@
package com.chameleonvision.network;
+import org.apache.commons.io.FileUtils;
+
+import java.io.File;
import java.io.IOException;
+import java.net.InetAddress;
import java.net.SocketException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class LinuxNetworking extends SysNetworking {
+ private static final String PATH = "/etc/dhcpcd.conf";
- @Override
- public boolean setDHCP() {
- String[] clearArgs = { "addr", "flush", "dev", networkInterface.name };
- try {
- int clearRetCode = shell.execute("ip", clearArgs);
- int dhcpRetCode = shell.execute("dhclient", networkInterface.name);
- return clearRetCode == 0 && dhcpRetCode == 0;
- } catch (IOException e) {
- e.printStackTrace();
- return false;
- }
- }
+ @Override
+ public boolean setDHCP() {
+ File dhcpConf = new File(PATH);
+ if (dhcpConf.exists()) {
+ try {
+ List lines = FileUtils.readLines(dhcpConf, StandardCharsets.UTF_8);
+ for (int i = 0; i < lines.size(); i++) {
+ String line = lines.get(i);
+ if (line.contains("interface " + networkInterface.name)) {
+ lines.remove(i);
+ for (int j = i; j < lines.size(); j++) {
+ String subInterface = lines.get(j);
+ if (subInterface.contains("static ip_address") || subInterface.contains("static routers")) {
+ lines.remove(j);
+ j--;
+ }
+ if (subInterface.contains("interface")) {
+ break;
+ }
+ }
+ FileUtils.writeLines(dhcpConf, lines);
+ return true;
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
- @Override
- public boolean setHostname(String newHostname) {
- String[] setHostnameArgs = { "set-hostname", newHostname };
- try {
- var setHostnameRetCode = shell.execute("hostnamectl", setHostnameArgs);
- return setHostnameRetCode == 0;
- } catch(Exception e) {
- e.printStackTrace();
- return false;
- }
- }
+ } else {
+ System.err.println("dhcpcd5 is not installed cant set ip");
+ return false;
+ }
+ return true;
+ }
- @Override
- public boolean setStatic(String ipAddress, String netmask, String gateway, String broadcast) {
- try {
- String[] clearArgs = { "addr", "flush", "dev", networkInterface.name };
- String[] setIPArgs = { "addr", "add", String.format("%s/%s", ipAddress, netmask), "broadcast", broadcast, "dev", networkInterface.name };
- String[] setGatewayArgs = { "route", "replace", "default", "via", gateway, "dev", networkInterface.name };
+ @Override
+ public boolean setHostname(String newHostname) {
+ String[] setHostnameArgs = {"set-hostname", newHostname};
+ try {
+ var setHostnameRetCode = shell.execute("hostnamectl", setHostnameArgs);
+ return setHostnameRetCode == 0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
- int clearRetCode = shell.execute("ip", clearArgs);
- int setIPRetCode = shell.execute("ip", setIPArgs);
- int setGatewayRetCode = shell.execute("ip", setGatewayArgs);
+ @Override
+ public boolean setStatic(String ipAddress, String netmask, String gateway) {
+ setDHCP(); // clean up old static interface
+ File dhcpConf = new File(PATH);
+ try {
+ List lines = FileUtils.readLines(dhcpConf, StandardCharsets.UTF_8);
+ lines.add("interface " + networkInterface.name);
+ InetAddress iNetMask = InetAddress.getByName(netmask);
+ int prefix = NetmaskToCIDR.convertNetmaskToCIDR(iNetMask);
+ lines.add("static ip_address " + ipAddress + "/" + prefix);
+ lines.add("static routers " + gateway);
+ FileUtils.writeLines(dhcpConf, lines);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return 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;
- }
+ @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<>();
- List goodInterfaces = new ArrayList<>();
+ for (var netInterface : netInterfaces) {
+ if (netInterface.getDisplayName().contains("lo")) continue;
+ if (!netInterface.isUp()) continue;
+ goodInterfaces.add(netInterface);
+ }
+ return goodInterfaces;
- for (var netInterface : netInterfaces) {
- if (netInterface.getDisplayName().contains("lo")) continue;
- if (!netInterface.isUp()) continue;
- goodInterfaces.add(netInterface);
- }
- return goodInterfaces;
-
- }
+ }
}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/NetmaskToCIDR.java b/chameleon-server/src/main/java/com/chameleonvision/network/NetmaskToCIDR.java
new file mode 100644
index 000000000..84673605f
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/network/NetmaskToCIDR.java
@@ -0,0 +1,29 @@
+package com.chameleonvision.network;
+
+import java.net.InetAddress;
+
+public class NetmaskToCIDR {
+ //code belongs to https://stackoverflow.com/questions/19531411/calculate-cidr-from-a-given-netmask-java
+ public static int convertNetmaskToCIDR(InetAddress netmask) {
+
+ byte[] netmaskBytes = netmask.getAddress();
+ int cidr = 0;
+ boolean zero = false;
+ for (byte b : netmaskBytes) {
+ int mask = 0x80;
+
+ for (int i = 0; i < 8; i++) {
+ int result = b & mask;
+ if (result == 0) {
+ zero = true;
+ } else if (zero) {
+ throw new IllegalArgumentException("Invalid netmask.");
+ } else {
+ cidr++;
+ }
+ mask >>>= 1;
+ }
+ }
+ return cidr;
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/NetworkManager.java b/chameleon-server/src/main/java/com/chameleonvision/network/NetworkManager.java
index d505199cd..60a99b8f1 100644
--- a/chameleon-server/src/main/java/com/chameleonvision/network/NetworkManager.java
+++ b/chameleon-server/src/main/java/com/chameleonvision/network/NetworkManager.java
@@ -9,44 +9,45 @@ import java.util.ArrayList;
import java.util.List;
public class NetworkManager {
- private NetworkManager() {}
+ private NetworkManager() {
+ }
- private static SysNetworking networking;
- private static boolean isManaged = false;
+ private static SysNetworking networking;
+ private static boolean isManaged = false;
- public static void initialize(boolean manage) {
- isManaged = manage;
- if (!isManaged) {
- return;
- }
+ public static void initialize(boolean manage) {
+ isManaged = manage;
+ if (!isManaged) {
+ return;
+ }
- Platform platform = Platform.CurrentPlatform;
+ Platform platform = Platform.CurrentPlatform;
- if (platform.isLinux()) {
- networking = new LinuxNetworking();
- } else if (platform.isWindows()) {
+ 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;
- }
+ }
- if (networking == null) {
- throw new RuntimeException("Failed to detect platform!");
- }
+ if (networking == null) {
+ throw new RuntimeException("Failed to detect platform!");
+ }
- List interfaces = new ArrayList<>();
- List goodInterfaces = new ArrayList<>();
+ List interfaces = new ArrayList<>();
+ List goodInterfaces = new ArrayList<>();
- try {
- interfaces = networking.getNetworkInterfaces();
- } catch (SocketException e) {
- e.printStackTrace();
- }
+ try {
+ interfaces = networking.getNetworkInterfaces();
+ } catch (SocketException e) {
+ e.printStackTrace();
+ }
var teamBytes = NetworkManager.GetTeamNumberIPBytes(ConfigManager.settings.teamNumber);
if (interfaces.size() > 0) {
- for (var inetface : interfaces) {
+ for (var inetface : interfaces) {
for (var inetfaceAddr : inetface.getInterfaceAddresses()) {
var rawAddr = inetfaceAddr.getAddress().getAddress();
if (rawAddr.length > 4) continue;
@@ -54,74 +55,53 @@ public class NetworkManager {
goodInterfaces.add(new NetworkInterface(inetface, inetfaceAddr));
}
}
- }
+ }
- if (goodInterfaces.size() == 0) {
- isManaged = false;
- System.err.println("No valid network interfaces found! Staying unmanaged.");
- return;
- }
+ if (goodInterfaces.size() == 0) {
+ isManaged = false;
+ System.err.println("No valid network interfaces found! Staying unmanaged.");
+ return;
+ }
- NetworkInterface 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 byte[] GetTeamNumberIPBytes(int teamNumber) {
- return new byte[]{(byte) (teamNumber / 100), (byte) (teamNumber % 100)};
- }
-
- private static boolean loadFromGeneralSettings() {
- if (!isManaged) {
- return true;
- }
-
- var genSettings = ConfigManager.settings;
- boolean isStatic = genSettings.connectionType.equals(NetworkIPMode.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();
+ NetworkInterface botInterface = goodInterfaces.get(0);
+ networking.setNetworkInterface(botInterface);
+ } else {
+ isManaged = false;
+ System.err.println("No valid network interfaces found! Staying unmanaged.");
+ }
}
- 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 byte[] GetTeamNumberIPBytes(int teamNumber) {
+ return new byte[]{(byte) (teamNumber / 100), (byte) (teamNumber % 100)};
}
- private static boolean setHostname(String hostname) {
- if (!isManaged) {
- return true;
- }
- return networking.setHostname(hostname);
+
+ private static boolean setDHCP() {
+ if (!isManaged) {
+ return true;
+ }
+ return networking.setDHCP();
+ }
+
+ private static boolean setStatic(String ipAddress, String netmask, String gateway) {
+ if (!isManaged) {
+ return true;
+ }
+ return networking.setStatic(ipAddress, netmask, gateway);
+ }
+
+ public static boolean setHostname(String hostname) {
+ if (!isManaged) {
+ return true;
+ }
+ return networking.setHostname(hostname);
+ }
+
+ public static boolean setNetwork(boolean isStatic, String ip, String netmask, String gateway) {
+ if (isStatic) {
+ return setStatic(ip, netmask, gateway);
+ } else {
+ return setDHCP();
+ }
}
}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/SysNetworking.java b/chameleon-server/src/main/java/com/chameleonvision/network/SysNetworking.java
index 63a609984..7073809fb 100644
--- a/chameleon-server/src/main/java/com/chameleonvision/network/SysNetworking.java
+++ b/chameleon-server/src/main/java/com/chameleonvision/network/SysNetworking.java
@@ -30,7 +30,7 @@ public abstract class SysNetworking {
}
public abstract boolean setDHCP();
public abstract boolean setHostname(String hostname);
- public abstract boolean setStatic(String ipAddress, String netmask, String gateway, String broadcast);
+ public abstract boolean setStatic(String ipAddress, String netmask, String gateway);
public abstract List getNetworkInterfaces() throws SocketException;
}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/WindowsNetworking.java b/chameleon-server/src/main/java/com/chameleonvision/network/WindowsNetworking.java
index d03da14e2..c6fdae74f 100644
--- a/chameleon-server/src/main/java/com/chameleonvision/network/WindowsNetworking.java
+++ b/chameleon-server/src/main/java/com/chameleonvision/network/WindowsNetworking.java
@@ -32,7 +32,7 @@ public class WindowsNetworking extends SysNetworking {
}
@Override
- public boolean setStatic(String ipAddress, String netmask, String gateway, String broadcast) {
+ public boolean setStatic(String ipAddress, String netmask, String gateway) {
return false;
}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/web/RequestHandler.java b/chameleon-server/src/main/java/com/chameleonvision/web/RequestHandler.java
index 55bc5e163..af82b6448 100644
--- a/chameleon-server/src/main/java/com/chameleonvision/web/RequestHandler.java
+++ b/chameleon-server/src/main/java/com/chameleonvision/web/RequestHandler.java
@@ -4,6 +4,7 @@ import com.chameleonvision.Exceptions.DuplicatedKeyException;
import com.chameleonvision.Main;
import com.chameleonvision.config.ConfigManager;
import com.chameleonvision.network.NetworkIPMode;
+import com.chameleonvision.network.NetworkManager;
import com.chameleonvision.networktables.NetworkTablesManager;
import com.chameleonvision.util.Helpers;
import com.chameleonvision.util.Platform;
@@ -53,8 +54,17 @@ public class RequestHandler {
ConfigManager.settings.gateway = (String) map.get("gateway");
ConfigManager.settings.hostname = (String) map.get("hostname");
ConfigManager.saveGeneralSettings();
+ // setting up network config after saving
+ boolean isStatic = ConfigManager.settings.connectionType.equals(NetworkIPMode.STATIC);
+
+ if (NetworkManager.setHostname(ConfigManager.settings.hostname) &&
+ NetworkManager.setNetwork(isStatic, ConfigManager.settings.ip, ConfigManager.settings.netmask, ConfigManager.settings.gateway)) {
+ ctx.status(200);
+ } else {
+ ctx.result("something went wrong while setting network configuration");
+ ctx.status(501);
+ }
SocketHandler.sendFullSettings();
- ctx.status(200);
} catch (JsonProcessingException e) {
ctx.status(500);
}