diff --git a/photon-client/src/store/index.js b/photon-client/src/store/index.js index a4673b7c3..4d9acb280 100644 --- a/photon-client/src/store/index.js +++ b/photon-client/src/store/index.js @@ -19,6 +19,8 @@ export default new Vuex.Store({ connected: false, address: "", clients: 0, + }, + networkInfo: { possibleRios: ["Loading..."], deviceips: ["Loading..."], }, @@ -155,6 +157,7 @@ export default new Vuex.Store({ calibrationData: set('calibrationData'), metrics: set('metrics'), ntConnectionInfo: set('ntConnectionInfo'), + networkInfo: set('networkInfo'), backendConnected: set('backendConnected'), logString: (state, newStr) => { const str = state.logMessages; diff --git a/photon-client/src/views/SettingsViews/Networking.vue b/photon-client/src/views/SettingsViews/Networking.vue index 00df79c38..914cfd528 100644 --- a/photon-client/src/views/SettingsViews/Networking.vue +++ b/photon-client/src/views/SettingsViews/Networking.vue @@ -87,7 +87,7 @@ {{ value }} @@ -115,7 +115,7 @@ {{ value }} diff --git a/photon-core/src/main/java/org/photonvision/common/dataflow/networktables/NetworkTablesManager.java b/photon-core/src/main/java/org/photonvision/common/dataflow/networktables/NetworkTablesManager.java index 01de464cf..3fadb11aa 100644 --- a/photon-core/src/main/java/org/photonvision/common/dataflow/networktables/NetworkTablesManager.java +++ b/photon-core/src/main/java/org/photonvision/common/dataflow/networktables/NetworkTablesManager.java @@ -17,20 +17,12 @@ package org.photonvision.common.dataflow.networktables; -import edu.wpi.first.cscore.CameraServerJNI; import edu.wpi.first.networktables.LogMessage; import edu.wpi.first.networktables.NetworkTable; import edu.wpi.first.networktables.NetworkTableInstance; -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.function.Consumer; import org.photonvision.PhotonVersion; -import org.photonvision.common.configuration.ConfigManager; import org.photonvision.common.configuration.NetworkConfig; import org.photonvision.common.dataflow.DataChangeService; import org.photonvision.common.dataflow.events.OutgoingUIEvent; @@ -87,6 +79,7 @@ public class NetworkTablesManager { private void broadcastConnectedStatusImpl() { HashMap map = new HashMap<>(); var subMap = new HashMap(); + subMap.put("connected", ntInstance.isConnected()); if (ntInstance.isConnected()) { var connections = getInstance().ntInstance.getConnections(); @@ -99,73 +92,6 @@ public class NetworkTablesManager { map.put("ntConnectionInfo", subMap); DataChangeService.getInstance() .publishEvent(new OutgoingUIEvent<>("networkTablesConnected", map)); - - // Seperate from the above so we don't hold stuff up - System.setProperty("java.net.preferIPv4Stack", "true"); - subMap.put( - "deviceips", - Arrays.stream(CameraServerJNI.getNetworkInterfaces()) - .filter(it -> !it.equals("0.0.0.0")) - .toArray()); - logger.info("Searching for rios"); - List possibleRioList = new ArrayList<>(); - for (var ip : CameraServerJNI.getNetworkInterfaces()) { - logger.info("Trying " + ip); - var possibleRioAddr = getPossibleRioAddress(ip); - if (possibleRioAddr != null) { - logger.info("Maybe found " + ip); - searchForHost(possibleRioList, possibleRioAddr); - } else { - logger.info("Didn't match RIO IP"); - } - } - String name = - "roboRIO-" - + ConfigManager.getInstance().getConfig().getNetworkConfig().teamNumber - + "-FRC.local"; - searchForHost(possibleRioList, name); - name = - "roboRIO-" - + ConfigManager.getInstance().getConfig().getNetworkConfig().teamNumber - + "-FRC.lan"; - searchForHost(possibleRioList, name); - name = - "roboRIO-" - + ConfigManager.getInstance().getConfig().getNetworkConfig().teamNumber - + "-FRC.frc-field.local"; - searchForHost(possibleRioList, name); - subMap.put("possibleRios", possibleRioList.toArray()); - DataChangeService.getInstance() - .publishEvent(new OutgoingUIEvent<>("networkTablesConnected", map)); - } - - String getPossibleRioAddress(String ip) { - try { - InetAddress addr = InetAddress.getByName(ip); - var address = addr.getAddress(); - if (address[0] != (byte) (10 & 0xff)) return null; - address[3] = (byte) (2 & 0xff); - return InetAddress.getByAddress(address).getHostAddress(); - } catch (UnknownHostException e) { - e.printStackTrace(); - } - return null; - } - - void searchForHost(List list, String hostname) { - try { - logger.info("Looking up " + hostname); - InetAddress testAddr = InetAddress.getByName(hostname); - logger.info("Pinging " + hostname); - var canContact = testAddr.isReachable(500); - if (canContact) { - logger.info("Was able to connect to " + hostname); - if (!list.contains(hostname)) list.add(hostname); - } else { - logger.info("Unable to reach " + hostname); - } - } catch (IOException ignored) { - } } private void broadcastVersion() { diff --git a/photon-core/src/main/java/org/photonvision/common/networking/RoborioFinder.java b/photon-core/src/main/java/org/photonvision/common/networking/RoborioFinder.java new file mode 100644 index 000000000..f94beb612 --- /dev/null +++ b/photon-core/src/main/java/org/photonvision/common/networking/RoborioFinder.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 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 . + */ + +package org.photonvision.common.networking; + +import edu.wpi.first.cscore.CameraServerJNI; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import org.photonvision.common.dataflow.DataChangeService; +import org.photonvision.common.dataflow.events.OutgoingUIEvent; +import org.photonvision.common.logging.LogGroup; +import org.photonvision.common.logging.Logger; + +public class RoborioFinder { + private static RoborioFinder instance; + private static final Logger logger = new Logger(RoborioFinder.class, LogGroup.General); + + public static RoborioFinder getInstance() { + if (instance == null) instance = new RoborioFinder(); + return instance; + } + + public void findRios() { + HashMap map = new HashMap<>(); + var subMap = new HashMap(); + // Seperate from the above so we don't hold stuff up + System.setProperty("java.net.preferIPv4Stack", "true"); + subMap.put( + "deviceips", + Arrays.stream(CameraServerJNI.getNetworkInterfaces()) + .filter(it -> !it.equals("0.0.0.0")) + .toArray()); + logger.info("Searching for rios"); + List possibleRioList = new ArrayList<>(); + for (var ip : CameraServerJNI.getNetworkInterfaces()) { + logger.info("Trying " + ip); + var possibleRioAddr = getPossibleRioAddress(ip); + if (possibleRioAddr != null) { + logger.info("Maybe found " + ip); + searchForHost(possibleRioList, possibleRioAddr); + } else { + logger.info("Didn't match RIO IP"); + } + } + + // String name = + // "roboRIO-" + // + + // ConfigManager.getInstance().getConfig().getNetworkConfig().teamNumber + // + "-FRC.local"; + // searchForHost(possibleRioList, name); + // name = + // "roboRIO-" + // + + // ConfigManager.getInstance().getConfig().getNetworkConfig().teamNumber + // + "-FRC.lan"; + // searchForHost(possibleRioList, name); + // name = + // "roboRIO-" + // + + // ConfigManager.getInstance().getConfig().getNetworkConfig().teamNumber + // + "-FRC.frc-field.local"; + // searchForHost(possibleRioList, name); + // subMap.put("possibleRios", possibleRioList.toArray()); + + subMap.put("possibleRios", possibleRioList.toArray()); + map.put("networkInfo", subMap); + DataChangeService.getInstance().publishEvent(new OutgoingUIEvent<>("deviceIpInfo", map)); + } + + String getPossibleRioAddress(String ip) { + try { + InetAddress addr = InetAddress.getByName(ip); + var address = addr.getAddress(); + if (address[0] != (byte) (10 & 0xff)) return null; + address[3] = (byte) (2 & 0xff); + return InetAddress.getByAddress(address).getHostAddress(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + return null; + } + + void searchForHost(List list, String hostname) { + try { + logger.info("Looking up " + hostname); + InetAddress testAddr = InetAddress.getByName(hostname); + logger.info("Pinging " + hostname); + var canContact = testAddr.isReachable(500); + if (canContact) { + logger.info("Was able to connect to " + hostname); + if (!list.contains(hostname)) list.add(hostname); + } else { + logger.info("Unable to reach " + hostname); + } + } catch (IOException ignored) { + } + } +} diff --git a/photon-server/src/main/java/org/photonvision/server/RequestHandler.java b/photon-server/src/main/java/org/photonvision/server/RequestHandler.java index 6b8c398eb..55b9f4c0f 100644 --- a/photon-server/src/main/java/org/photonvision/server/RequestHandler.java +++ b/photon-server/src/main/java/org/photonvision/server/RequestHandler.java @@ -40,6 +40,7 @@ import org.photonvision.common.hardware.metrics.MetricsPublisher; import org.photonvision.common.logging.LogGroup; import org.photonvision.common.logging.Logger; import org.photonvision.common.networking.NetworkManager; +import org.photonvision.common.networking.RoborioFinder; import org.photonvision.common.util.ShellExec; import org.photonvision.common.util.TimedTaskManager; import org.photonvision.common.util.file.ProgramDirectoryUtilities; @@ -280,6 +281,7 @@ public class RequestHandler { public static void sendMetrics(Context ctx) { MetricsPublisher.getInstance().publish(); + TimedTaskManager.getInstance().addOneShotTask(() -> RoborioFinder.getInstance().findRios(), 0); ctx.status(200); }