From 1f7ad712180d932a2e141556f8a6f82cef75e51b Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 25 Jun 2013 16:13:14 +0200 Subject: [PATCH] IDE network discovery now reacts to new networks: it monitors available IP addresses and, when one is added, it starts listening to bonjours coming from it --- app/src/cc/arduino/packages/Discovery.java | 2 +- .../cc/arduino/packages/DiscoveryManager.java | 17 +++--- .../discoverers/NetworkDiscovery.java | 52 +++++++++++++------ .../discoverers/network/NetworkChecker.java | 46 ++++++++++++++++ .../network/NetworkTopologyListener.java | 11 ++++ 5 files changed, 105 insertions(+), 23 deletions(-) create mode 100644 app/src/cc/arduino/packages/discoverers/network/NetworkChecker.java create mode 100644 app/src/cc/arduino/packages/discoverers/network/NetworkTopologyListener.java diff --git a/app/src/cc/arduino/packages/Discovery.java b/app/src/cc/arduino/packages/Discovery.java index 60cb54708..17ba91588 100644 --- a/app/src/cc/arduino/packages/Discovery.java +++ b/app/src/cc/arduino/packages/Discovery.java @@ -23,7 +23,7 @@ public interface Discovery { /** * Stop discovery service */ - public void stop(); + public void stop() throws Exception; /** * Return the list of discovered ports. diff --git a/app/src/cc/arduino/packages/DiscoveryManager.java b/app/src/cc/arduino/packages/DiscoveryManager.java index 4a002755f..8681acc9b 100644 --- a/app/src/cc/arduino/packages/DiscoveryManager.java +++ b/app/src/cc/arduino/packages/DiscoveryManager.java @@ -1,12 +1,12 @@ package cc.arduino.packages; -import static processing.app.I18n._; +import cc.arduino.packages.discoverers.NetworkDiscovery; +import cc.arduino.packages.discoverers.SerialDiscovery; import java.util.ArrayList; import java.util.List; -import cc.arduino.packages.discoverers.NetworkDiscovery; -import cc.arduino.packages.discoverers.SerialDiscovery; +import static processing.app.I18n._; public class DiscoveryManager { @@ -25,7 +25,7 @@ public class DiscoveryManager { e.printStackTrace(); } } - + Runtime.getRuntime().addShutdownHook(closeHook); } @@ -39,8 +39,13 @@ public class DiscoveryManager { private Thread closeHook = new Thread(new Runnable() { @Override public void run() { - for (Discovery d : discoverers) - d.stop(); + for (Discovery d : discoverers) { + try { + d.stop(); + } catch (Exception e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } } }); } diff --git a/app/src/cc/arduino/packages/discoverers/NetworkDiscovery.java b/app/src/cc/arduino/packages/discoverers/NetworkDiscovery.java index 630109ade..039e959e2 100644 --- a/app/src/cc/arduino/packages/discoverers/NetworkDiscovery.java +++ b/app/src/cc/arduino/packages/discoverers/NetworkDiscovery.java @@ -2,6 +2,7 @@ package cc.arduino.packages.discoverers; import cc.arduino.packages.BoardPort; import cc.arduino.packages.Discovery; +import cc.arduino.packages.discoverers.network.NetworkChecker; import processing.app.Base; import processing.app.helpers.PreferencesMap; import processing.app.zeroconf.jmdns.ArduinoDNSTaskStarter; @@ -12,17 +13,18 @@ import java.io.IOException; import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.util.*; -public class NetworkDiscovery implements Discovery, ServiceListener { +public class NetworkDiscovery implements Discovery, ServiceListener, cc.arduino.packages.discoverers.network.NetworkTopologyListener { + private Timer timer; private List ports; + private final Map mappedJmDNSs; public NetworkDiscovery() { DNSTaskStarter.Factory.setClassDelegate(new ArduinoDNSTaskStarter()); this.ports = new ArrayList(); + this.mappedJmDNSs = new Hashtable(); } @Override @@ -56,21 +58,14 @@ public class NetworkDiscovery implements Discovery, ServiceListener { @Override public void start() throws IOException { - for (InetAddress addr : NetworkTopologyDiscovery.Factory.getInstance().getInetAddresses()) { - JmDNS jmDNS = JmDNS.create(addr); - jmDNS.addServiceListener("_arduino._tcp.local.", this); - } + this.timer = new Timer(this.getClass().getName() + " timer"); + new NetworkChecker(this, NetworkTopologyDiscovery.Factory.getInstance()).start(timer); } @Override - public void stop() { - // Removed cleanup: is extremely slow on closing - - // try { - // jmDNS.close(); - // } catch (IOException e) { - // e.printStackTrace(); - // } + public void stop() throws IOException { + timer.purge(); + // we don't close each JmDNS instance as it's too slow } @Override @@ -130,4 +125,29 @@ public class NetworkDiscovery implements Discovery, ServiceListener { } } + @Override + public void inetAddressAdded(InetAddress address) { + if (mappedJmDNSs.containsKey(address)) { + return; + } + try { + JmDNS jmDNS = JmDNS.create(address); + jmDNS.addServiceListener("_arduino._tcp.local.", this); + mappedJmDNSs.put(address, jmDNS); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void inetAddressRemoved(InetAddress address) { + JmDNS jmDNS = mappedJmDNSs.remove(address); + if (jmDNS != null) { + try { + jmDNS.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } } diff --git a/app/src/cc/arduino/packages/discoverers/network/NetworkChecker.java b/app/src/cc/arduino/packages/discoverers/network/NetworkChecker.java new file mode 100644 index 000000000..8ee81b7a6 --- /dev/null +++ b/app/src/cc/arduino/packages/discoverers/network/NetworkChecker.java @@ -0,0 +1,46 @@ +package cc.arduino.packages.discoverers.network; + +import javax.jmdns.NetworkTopologyDiscovery; +import java.net.InetAddress; +import java.util.*; + +public class NetworkChecker extends TimerTask { + + private final NetworkTopologyListener topologyListener; + private final NetworkTopologyDiscovery topology; + + private Set knownAddresses; + + public NetworkChecker(NetworkTopologyListener topologyListener, NetworkTopologyDiscovery topology) { + super(); + this.topologyListener = topologyListener; + this.topology = topology; + this.knownAddresses = Collections.synchronizedSet(new HashSet()); + } + + public void start(Timer timer) { + timer.schedule(this, 0, 3000); + } + + @Override + public void run() { + try { + InetAddress[] curentAddresses = topology.getInetAddresses(); + Set current = new HashSet(curentAddresses.length); + for (InetAddress address : curentAddresses) { + current.add(address); + if (!knownAddresses.contains(address)) { + topologyListener.inetAddressAdded(address); + } + } + for (InetAddress address : knownAddresses) { + if (!current.contains(address)) { + topologyListener.inetAddressRemoved(address); + } + } + knownAddresses = current; + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/app/src/cc/arduino/packages/discoverers/network/NetworkTopologyListener.java b/app/src/cc/arduino/packages/discoverers/network/NetworkTopologyListener.java new file mode 100644 index 000000000..312deccb5 --- /dev/null +++ b/app/src/cc/arduino/packages/discoverers/network/NetworkTopologyListener.java @@ -0,0 +1,11 @@ +package cc.arduino.packages.discoverers.network; + +import java.net.InetAddress; + +public interface NetworkTopologyListener { + + void inetAddressAdded(InetAddress address); + + void inetAddressRemoved(InetAddress address); + +}