001/* 002 * Copyright (C) Photon Vision. 003 * 004 * This program is free software: you can redistribute it and/or modify 005 * it under the terms of the GNU General Public License as published by 006 * the Free Software Foundation, either version 3 of the License, or 007 * (at your option) any later version. 008 * 009 * This program is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU General Public License for more details. 013 * 014 * You should have received a copy of the GNU General Public License 015 * along with this program. If not, see <https://www.gnu.org/licenses/>. 016 */ 017 018package org.photonvision.common.networking; 019 020import edu.wpi.first.cscore.CameraServerJNI; 021import java.io.IOException; 022import java.net.InetAddress; 023import java.net.UnknownHostException; 024import java.util.ArrayList; 025import java.util.Arrays; 026import java.util.HashMap; 027import java.util.List; 028import org.photonvision.common.dataflow.DataChangeService; 029import org.photonvision.common.dataflow.events.OutgoingUIEvent; 030import org.photonvision.common.logging.LogGroup; 031import org.photonvision.common.logging.Logger; 032 033public class RoborioFinder { 034 private static RoborioFinder instance; 035 private static final Logger logger = new Logger(RoborioFinder.class, LogGroup.General); 036 037 public static RoborioFinder getInstance() { 038 if (instance == null) instance = new RoborioFinder(); 039 return instance; 040 } 041 042 public void findRios() { 043 HashMap<String, Object> map = new HashMap<>(); 044 var subMap = new HashMap<String, Object>(); 045 // Separate from the above so we don't hold stuff up 046 System.setProperty("java.net.preferIPv4Stack", "true"); 047 subMap.put( 048 "deviceIps", 049 Arrays.stream(CameraServerJNI.getNetworkInterfaces()) 050 .filter(it -> !it.equals("0.0.0.0")) 051 .toArray()); 052 logger.info("Searching for rios"); 053 List<String> possibleRioList = new ArrayList<>(); 054 for (var ip : CameraServerJNI.getNetworkInterfaces()) { 055 logger.info("Trying " + ip); 056 var possibleRioAddr = getPossibleRioAddress(ip); 057 if (possibleRioAddr != null) { 058 logger.info("Maybe found " + ip); 059 searchForHost(possibleRioList, possibleRioAddr); 060 } else { 061 logger.info("Didn't match RIO IP"); 062 } 063 } 064 065 // String name = 066 // "roboRIO-" 067 // + 068 // ConfigManager.getInstance().getConfig().getNetworkConfig().teamNumber 069 // + "-FRC.local"; 070 // searchForHost(possibleRioList, name); 071 // name = 072 // "roboRIO-" 073 // + 074 // ConfigManager.getInstance().getConfig().getNetworkConfig().teamNumber 075 // + "-FRC.lan"; 076 // searchForHost(possibleRioList, name); 077 // name = 078 // "roboRIO-" 079 // + 080 // ConfigManager.getInstance().getConfig().getNetworkConfig().teamNumber 081 // + "-FRC.frc-field.local"; 082 // searchForHost(possibleRioList, name); 083 // subMap.put("possibleRios", possibleRioList.toArray()); 084 085 subMap.put("possibleRios", possibleRioList.toArray()); 086 map.put("networkInfo", subMap); 087 DataChangeService.getInstance().publishEvent(new OutgoingUIEvent<>("deviceIpInfo", map)); 088 } 089 090 String getPossibleRioAddress(String ip) { 091 try { 092 InetAddress addr = InetAddress.getByName(ip); 093 var address = addr.getAddress(); 094 if (address[0] != (byte) (10 & 0xff)) return null; 095 address[3] = (byte) (2 & 0xff); 096 return InetAddress.getByAddress(address).getHostAddress(); 097 } catch (UnknownHostException e) { 098 e.printStackTrace(); 099 } 100 return null; 101 } 102 103 void searchForHost(List<String> list, String hostname) { 104 try { 105 logger.info("Looking up " + hostname); 106 InetAddress testAddr = InetAddress.getByName(hostname); 107 logger.info("Pinging " + hostname); 108 var canContact = testAddr.isReachable(500); 109 if (canContact) { 110 logger.info("Was able to connect to " + hostname); 111 if (!list.contains(hostname)) list.add(hostname); 112 } else { 113 logger.info("Unable to reach " + hostname); 114 } 115 } catch (IOException ignored) { 116 } 117 } 118}