From 79f49c4e18bb5f43538267e962e5ddce25923560 Mon Sep 17 00:00:00 2001 From: Thad House Date: Thu, 2 Jul 2026 21:14:54 -0700 Subject: [PATCH 1/2] Add a direct mDNS lookup to what is performed to find the robot --- build.gradle | 2 + .../systemcore/FirstDsDeployLocation.java | 11 +-- .../systemcore/MulticastDeployLocation.java | 74 +++++++++++++++++++ .../deploy/systemcore/NiDsDeployLocation.java | 10 +-- 4 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 src/main/java/org/wpilib/gradlerio/deploy/systemcore/MulticastDeployLocation.java diff --git a/build.gradle b/build.gradle index 9b495ee0..3d16df11 100644 --- a/build.gradle +++ b/build.gradle @@ -25,6 +25,8 @@ dependencies { api 'org.wpilib:native-utils:2027.10.0' + api 'org.jmdns:jmdns:3.6.3' + api 'de.undercouch:gradle-download-task:5.6.0' testImplementation('org.spockframework:spock-core:2.4-M6-groovy-4.0') { diff --git a/src/main/java/org/wpilib/gradlerio/deploy/systemcore/FirstDsDeployLocation.java b/src/main/java/org/wpilib/gradlerio/deploy/systemcore/FirstDsDeployLocation.java index 7100fa57..accd7bd6 100644 --- a/src/main/java/org/wpilib/gradlerio/deploy/systemcore/FirstDsDeployLocation.java +++ b/src/main/java/org/wpilib/gradlerio/deploy/systemcore/FirstDsDeployLocation.java @@ -13,7 +13,6 @@ import javax.inject.Inject; import com.google.gson.Gson; -import com.google.gson.annotations.SerializedName; import org.wpilib.deployutils.deploy.target.RemoteTarget; import org.wpilib.deployutils.deploy.target.discovery.action.DiscoveryAction; @@ -29,9 +28,9 @@ public FirstDsDeployLocation(String name, RemoteTarget target) { super(name, target); } - private String dsAddress = "localhost"; + private final String dsAddress = "localhost"; private Optional cachedAddress = Optional.empty(); - private ETLogger log = ETLoggerFactory.INSTANCE.create("FirstDsDeployLocation"); + private final ETLogger log = ETLoggerFactory.INSTANCE.create("FirstDsDeployLocation"); private int timeout = 1000; private int port = 6770; @@ -56,11 +55,6 @@ public String getAddress() { return cachedAddress.get(); } - @Override - public void setAddress(String address) { - this.dsAddress = address; - } - @Override public DiscoveryAction createAction() { return new SshDiscoveryAction(this); @@ -73,7 +67,6 @@ private static class DsJsonData { @Override public void discover() { - cachedAddress = Optional.of("FIRST DS Connection Issue"); cachedAddress = Optional.of(determineAddress()); } diff --git a/src/main/java/org/wpilib/gradlerio/deploy/systemcore/MulticastDeployLocation.java b/src/main/java/org/wpilib/gradlerio/deploy/systemcore/MulticastDeployLocation.java new file mode 100644 index 00000000..acdbaae3 --- /dev/null +++ b/src/main/java/org/wpilib/gradlerio/deploy/systemcore/MulticastDeployLocation.java @@ -0,0 +1,74 @@ +package org.wpilib.gradlerio.deploy.systemcore; + +import java.io.IOException; +import java.net.InetAddress; +import java.util.Optional; + +import javax.inject.Inject; +import javax.jmdns.JmDNS; + +import org.wpilib.deployutils.deploy.target.RemoteTarget; +import org.wpilib.deployutils.deploy.target.discovery.action.DiscoveryAction; +import org.wpilib.deployutils.deploy.target.discovery.action.SshDiscoveryAction; +import org.wpilib.deployutils.deploy.target.location.SshDeployLocation; +import org.wpilib.deployutils.log.ETLogger; +import org.wpilib.deployutils.log.ETLoggerFactory; + +public class MulticastDeployLocation extends SshDeployLocation { + + @Inject + public MulticastDeployLocation(String name, RemoteTarget target) { + super(name, target); + } + + private final String serviceName = "SystemCore-FIRST"; + private final String serviceType = "_SystemCore._tcp.local."; + private Optional cachedAddress = Optional.empty(); + private final ETLogger log = ETLoggerFactory.INSTANCE.create("MulticastDeployLocation"); + private int timeout = 5000; + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + @Override + public String getAddress() { + return cachedAddress.get(); + } + + @Override + public DiscoveryAction createAction() { + return new SshDiscoveryAction(this); + } + + @Override + public void discover() { + cachedAddress = Optional.of(determineAddress()); + } + + private String determineAddress() { + log.debug("mDNS Lookup: Attempting to determine robot IP address"); + + try (JmDNS jmdns = JmDNS.create(InetAddress.getLocalHost())) { + var serviceInfo = jmdns.getServiceInfo(serviceType, serviceName, timeout); + if (serviceInfo != null) { + var addresses = serviceInfo.getInet4Addresses(); + if (addresses.length > 0) { + String ipAddress = addresses[0].getHostAddress(); + cachedAddress = Optional.of(ipAddress); + log.debug("mDNS Lookup: Found robot IP address: " + ipAddress); + return ipAddress; + } + } + log.debug("mDNS Lookup: Could not find robot IPv4 address via mDNS"); + throw new RuntimeException("Could not find robot IPv4 address via mDNS"); + } catch (IOException e) { + log.debug("mDNS Lookup: IOException occurred while trying to determine robot IP address"); + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/org/wpilib/gradlerio/deploy/systemcore/NiDsDeployLocation.java b/src/main/java/org/wpilib/gradlerio/deploy/systemcore/NiDsDeployLocation.java index b4a01eb3..09690738 100644 --- a/src/main/java/org/wpilib/gradlerio/deploy/systemcore/NiDsDeployLocation.java +++ b/src/main/java/org/wpilib/gradlerio/deploy/systemcore/NiDsDeployLocation.java @@ -29,9 +29,9 @@ public NiDsDeployLocation(String name, RemoteTarget target) { super(name, target); } - private String dsAddress = "localhost"; + private final String dsAddress = "localhost"; private Optional cachedAddress = Optional.empty(); - private ETLogger log = ETLoggerFactory.INSTANCE.create("NiDsDeployLocation"); + private final ETLogger log = ETLoggerFactory.INSTANCE.create("NiDsDeployLocation"); private int timeout = 1000; private int port = 1742; @@ -56,11 +56,6 @@ public String getAddress() { return cachedAddress.get(); } - @Override - public void setAddress(String address) { - this.dsAddress = address; - } - @Override public DiscoveryAction createAction() { return new SshDiscoveryAction(this); @@ -74,7 +69,6 @@ private static class DsJsonData { @Override public void discover() { - cachedAddress = Optional.of("NI DS Connection Issue"); cachedAddress = Optional.of(determineAddress()); } From ab74809ec085e20850537effcadf59d6176c35c3 Mon Sep 17 00:00:00 2001 From: Thad House Date: Thu, 2 Jul 2026 21:21:32 -0700 Subject: [PATCH 2/2] Add mDNS to default --- .../org/wpilib/gradlerio/deploy/WPILibDeployPlugin.java | 2 ++ .../org/wpilib/gradlerio/deploy/systemcore/SystemCore.java | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/org/wpilib/gradlerio/deploy/WPILibDeployPlugin.java b/src/main/java/org/wpilib/gradlerio/deploy/WPILibDeployPlugin.java index 83b14200..64206f56 100644 --- a/src/main/java/org/wpilib/gradlerio/deploy/WPILibDeployPlugin.java +++ b/src/main/java/org/wpilib/gradlerio/deploy/WPILibDeployPlugin.java @@ -10,6 +10,7 @@ import org.wpilib.deployutils.deploy.artifact.Artifact; import org.wpilib.deployutils.deploy.context.DeployContext; import org.wpilib.deployutils.deploy.target.location.DeployLocation; +import org.wpilib.gradlerio.deploy.systemcore.MulticastDeployLocation; import org.wpilib.gradlerio.deploy.systemcore.NiDsDeployLocation; import org.wpilib.gradlerio.deploy.systemcore.FirstDsDeployLocation; import org.wpilib.gradlerio.deploy.systemcore.WPILibJNILibraryArtifact; @@ -41,6 +42,7 @@ private void configureSystemCoreTypes(SystemCore target) { NamedObjectFactory.registerType(NiDsDeployLocation.class, locations, target, objects); NamedObjectFactory.registerType(FirstDsDeployLocation.class, locations, target, objects); + NamedObjectFactory.registerType(MulticastDeployLocation.class, locations, target, objects); } @Override diff --git a/src/main/java/org/wpilib/gradlerio/deploy/systemcore/SystemCore.java b/src/main/java/org/wpilib/gradlerio/deploy/systemcore/SystemCore.java index 7a0c6bfe..d86f970c 100644 --- a/src/main/java/org/wpilib/gradlerio/deploy/systemcore/SystemCore.java +++ b/src/main/java/org/wpilib/gradlerio/deploy/systemcore/SystemCore.java @@ -97,6 +97,12 @@ public void setAddresses(String... addresses) { ds.setPassword(password); ds.setIpv6(false); }); + + getLocations().create("mdns", MulticastDeployLocation.class, mdns -> { + mdns.setUser(username); + mdns.setPassword(password); + mdns.setIpv6(false); + }); } public void addAddress(String address) {