mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-21 01:01:41 +00:00
Merge branch 'linux-networking' into dev
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.javalin:javalin:3.7.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.61" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.3.61" level="project" />
|
||||
@@ -36,6 +37,7 @@
|
||||
<orderEntry type="library" name="Maven: org.json:json:20190722" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-nop:1.7.26" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.msgpack:msgpack-core:0.8.18" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.msgpack:jackson-dataformat-msgpack:0.8.18" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
|
||||
|
||||
@@ -86,6 +86,11 @@
|
||||
<artifactId>commons-math3</artifactId>
|
||||
<version>3.6.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.msgpack</groupId>
|
||||
<artifactId>msgpack-core</artifactId>
|
||||
|
||||
@@ -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<String> 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<String> 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<java.net.NetworkInterface> getNetworkInterfaces() throws SocketException {
|
||||
List<java.net.NetworkInterface> netInterfaces;
|
||||
try {
|
||||
netInterfaces = Collections.list(java.net.NetworkInterface.getNetworkInterfaces());
|
||||
} catch (SocketException e) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public List<java.net.NetworkInterface> getNetworkInterfaces() throws SocketException {
|
||||
List<java.net.NetworkInterface> netInterfaces;
|
||||
try {
|
||||
netInterfaces = Collections.list(java.net.NetworkInterface.getNetworkInterfaces());
|
||||
} catch (SocketException e) {
|
||||
return null;
|
||||
}
|
||||
List<java.net.NetworkInterface> goodInterfaces = new ArrayList<>();
|
||||
|
||||
List<java.net.NetworkInterface> 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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<java.net.NetworkInterface> interfaces = new ArrayList<>();
|
||||
List<NetworkInterface> goodInterfaces = new ArrayList<>();
|
||||
List<java.net.NetworkInterface> interfaces = new ArrayList<>();
|
||||
List<NetworkInterface> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<java.net.NetworkInterface> getNetworkInterfaces() throws SocketException;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user