mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-20 00:51:41 +00:00
Fix static IP and network settings on Pi
This commit is contained in:
@@ -162,7 +162,7 @@ public class Main {
|
||||
// Force load the hardware manager
|
||||
HardwareManager.getInstance();
|
||||
|
||||
NetworkManager.getInstance().initialize(false);
|
||||
NetworkManager.getInstance().reinitialize();
|
||||
|
||||
NetworkTablesManager.getInstance()
|
||||
.setConfig(ConfigManager.getInstance().getConfig().getNetworkConfig());
|
||||
|
||||
@@ -26,7 +26,6 @@ public class NetworkConfig {
|
||||
public int teamNumber = 0;
|
||||
public NetworkMode connectionType = NetworkMode.DHCP;
|
||||
public String staticIp = "";
|
||||
public String netmask = "";
|
||||
public String hostname = "photonvision";
|
||||
public boolean runNTServer = false;
|
||||
|
||||
@@ -38,18 +37,16 @@ public class NetworkConfig {
|
||||
int teamNumber,
|
||||
NetworkMode connectionType,
|
||||
String staticIp,
|
||||
String netmask,
|
||||
String hostname,
|
||||
boolean runNTServer,
|
||||
boolean shouldManage) {
|
||||
this.teamNumber = teamNumber;
|
||||
this.connectionType = connectionType;
|
||||
this.staticIp = staticIp;
|
||||
this.netmask = netmask;
|
||||
this.hostname = hostname;
|
||||
this.runNTServer = runNTServer;
|
||||
|
||||
this.shouldManage = shouldManage || Platform.isRaspberryPi();
|
||||
this.shouldManage = shouldManage;
|
||||
}
|
||||
|
||||
public static NetworkConfig fromHashMap(Map<String, Object> map) {
|
||||
@@ -60,7 +57,6 @@ public class NetworkConfig {
|
||||
ret.shouldManage = (Boolean) map.get("supported");
|
||||
ret.connectionType = NetworkMode.values()[(Integer) map.get("connectionType")];
|
||||
ret.staticIp = (String) map.get("staticIp");
|
||||
ret.netmask = (String) map.get("netmask");
|
||||
ret.hostname = (String) map.get("hostname");
|
||||
ret.runNTServer = (Boolean) map.get("runNTServer");
|
||||
return ret;
|
||||
@@ -69,12 +65,15 @@ public class NetworkConfig {
|
||||
public HashMap<String, Object> toHashMap() {
|
||||
HashMap<String, Object> tmp = new HashMap<>();
|
||||
tmp.put("teamNumber", teamNumber);
|
||||
tmp.put("supported", shouldManage);
|
||||
tmp.put("supported", shouldManage());
|
||||
tmp.put("connectionType", connectionType.ordinal());
|
||||
tmp.put("staticIp", staticIp);
|
||||
tmp.put("netmask", netmask);
|
||||
tmp.put("hostname", hostname);
|
||||
tmp.put("runNTServer", runNTServer);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
public boolean shouldManage() {
|
||||
return this.shouldManage || Platform.isRaspberryPi();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,6 @@ public class NetworkTablesManager {
|
||||
|
||||
private static final Logger logger = new Logger(NetworkTablesManager.class, LogGroup.General);
|
||||
|
||||
public boolean isServer = false;
|
||||
|
||||
private static class NTLogger implements Consumer<LogMessage> {
|
||||
|
||||
private boolean hasReportedConnectionFailure = false;
|
||||
@@ -77,7 +75,6 @@ public class NetworkTablesManager {
|
||||
}
|
||||
|
||||
private void setClientMode(int teamNumber) {
|
||||
isServer = false;
|
||||
logger.info("Starting NT Client");
|
||||
ntInstance.stopServer();
|
||||
|
||||
@@ -91,7 +88,6 @@ public class NetworkTablesManager {
|
||||
}
|
||||
|
||||
private void setServerMode() {
|
||||
isServer = true;
|
||||
logger.info("Starting NT Server");
|
||||
ntInstance.stopClient();
|
||||
ntInstance.startServer();
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Photon Vision.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.photonvision.common.networking;
|
||||
|
||||
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;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.photonvision.common.logging.LogGroup;
|
||||
import org.photonvision.common.logging.Logger;
|
||||
|
||||
public class LinuxNetworking extends SysNetworking {
|
||||
private static final String PATH = "/etc/dhcpcd.conf";
|
||||
|
||||
private Logger logger = new Logger(LinuxNetworking.class, LogGroup.General);
|
||||
|
||||
@Override
|
||||
public boolean setDHCP() {
|
||||
File dhcpConf = new File(PATH);
|
||||
logger.debug("Removing static IP from " + 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.startsWith("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) {
|
||||
logger.error("Failed to set DHCP!", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
logger.error("dhcpcd5 is not installed, unable to set IP.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setHostname(String newHostname) {
|
||||
try {
|
||||
var setHostnameRetCode = shell.execute("hostnamectl", "set-hostname", newHostname);
|
||||
return setHostnameRetCode == 0;
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to set hostname!", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setStatic(String ipAddress, String netmask) {
|
||||
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 = convertNetmaskToCIDR(iNetMask);
|
||||
lines.add("static ip_address=" + ipAddress + "/" + prefix);
|
||||
FileUtils.writeLines(dhcpConf, lines);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to set Static IP!", e);
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -76,12 +76,20 @@ public class NetworkManager {
|
||||
}
|
||||
|
||||
if (config.connectionType == NetworkMode.DHCP) {
|
||||
return; // TODO do we need to reconnect or something?
|
||||
var shell = new ShellExec();
|
||||
try {
|
||||
if (config.staticIp != "") {
|
||||
shell.executeBashCommand("ip addr del " + config.staticIp + "/8 dev eth0");
|
||||
}
|
||||
shell.executeBashCommand("dhclient eth0");
|
||||
} catch (Exception e) {
|
||||
logger.error("Exception while setting DHCP!");
|
||||
}
|
||||
} else if (config.connectionType == NetworkMode.STATIC) {
|
||||
var shell = new ShellExec();
|
||||
if (config.staticIp.length() > 0) {
|
||||
try {
|
||||
shell.executeBashCommand("ip addr add " + config.staticIp + "/24" + " dev eth0");
|
||||
shell.executeBashCommand("ip addr add " + config.staticIp + "/8" + " dev eth0");
|
||||
} catch (Exception e) {
|
||||
logger.error("Error while setting static IP!", e);
|
||||
}
|
||||
@@ -95,6 +103,6 @@ public class NetworkManager {
|
||||
}
|
||||
|
||||
public void reinitialize() {
|
||||
initialize(ConfigManager.getInstance().getConfig().getNetworkConfig().shouldManage);
|
||||
initialize(ConfigManager.getInstance().getConfig().getNetworkConfig().shouldManage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Photon Vision.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.photonvision.common.networking;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketException;
|
||||
import java.util.List;
|
||||
import org.photonvision.common.util.ShellExec;
|
||||
|
||||
public abstract class SysNetworking {
|
||||
NetworkInterface networkInterface;
|
||||
ShellExec shell = new ShellExec(true, true);
|
||||
|
||||
private String hostname = getHostname();
|
||||
|
||||
public String getHostname() {
|
||||
if (hostname == null) {
|
||||
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;
|
||||
}
|
||||
} else return hostname;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
public abstract List<java.net.NetworkInterface> getNetworkInterfaces() throws SocketException;
|
||||
}
|
||||
@@ -73,15 +73,8 @@ public class RequestHandler {
|
||||
public static void onGeneralSettings(Context context) throws JsonProcessingException {
|
||||
Map<String, Object> map =
|
||||
(Map<String, Object>) kObjectMapper.readValue(context.body(), Map.class);
|
||||
var networking =
|
||||
(Map<String, Object>)
|
||||
map.get("networkSettings"); // teamNumber (int), supported (bool), connectionType (int),
|
||||
// staticIp (str), netmask (str), gateway (str), hostname (str)
|
||||
var lighting =
|
||||
(Map<String, Object>) map.get("lighting"); // supported (true/false), brightness (int)
|
||||
// TODO do stuff with lighting
|
||||
|
||||
var networkConfig = NetworkConfig.fromHashMap(networking);
|
||||
var networkConfig = NetworkConfig.fromHashMap(map);
|
||||
ConfigManager.getInstance().setNetworkSettings(networkConfig);
|
||||
ConfigManager.getInstance().requestSave();
|
||||
NetworkManager.getInstance().reinitialize();
|
||||
|
||||
Reference in New Issue
Block a user