diff --git a/arduino-core/src/cc/arduino/packages/UploaderFactory.java b/arduino-core/src/cc/arduino/packages/UploaderFactory.java index 860d3da8f..74b993433 100644 --- a/arduino-core/src/cc/arduino/packages/UploaderFactory.java +++ b/arduino-core/src/cc/arduino/packages/UploaderFactory.java @@ -31,6 +31,7 @@ package cc.arduino.packages; import cc.arduino.packages.uploaders.SSHUploader; import cc.arduino.packages.uploaders.SerialUploader; +import cc.arduino.packages.uploaders.GenericNetworkUploader; import processing.app.debug.TargetBoard; public class UploaderFactory { @@ -41,6 +42,9 @@ public class UploaderFactory { } if (port != null && "network".equals(port.getProtocol())) { + if(port.getPrefs().get("ssh_upload").contentEquals("no")){ + return new GenericNetworkUploader(port); + } return new SSHUploader(port); } diff --git a/arduino-core/src/cc/arduino/packages/discoverers/NetworkDiscovery.java b/arduino-core/src/cc/arduino/packages/discoverers/NetworkDiscovery.java index 6f8fa10a6..ebbb8c50d 100644 --- a/arduino-core/src/cc/arduino/packages/discoverers/NetworkDiscovery.java +++ b/arduino-core/src/cc/arduino/packages/discoverers/NetworkDiscovery.java @@ -144,6 +144,21 @@ public class NetworkDiscovery implements Discovery, ServiceListener, cc.arduino. port.getPrefs().put("board", board); port.getPrefs().put("distro_version", info.getPropertyString("distro_version")); port.getPrefs().put("port", "" + info.getPort()); + + //Add additional fields to permit generic ota updates + //and make sure we do not intefere with Arduino boards + // define "ssh_upload=no" TXT property to use generic uploader + // define "tcp_check=no" TXT property if you are not using TCP + // define "auth_upload=yes" TXT property if you want to use authenticated generic upload + String useSSH = info.getPropertyString("ssh_upload"); + String checkTCP = info.getPropertyString("tcp_check"); + String useAuth = info.getPropertyString("auth_upload"); + if(useSSH == null || !useSSH.contentEquals("no")) useSSH = "yes"; + if(checkTCP == null || !checkTCP.contentEquals("no")) checkTCP = "yes"; + if(useAuth == null || !useAuth.contentEquals("yes")) useAuth = "no"; + port.getPrefs().put("ssh_upload", useSSH); + port.getPrefs().put("tcp_check", checkTCP); + port.getPrefs().put("auth_upload", useAuth); } String label = name + " at " + address; diff --git a/arduino-core/src/cc/arduino/packages/discoverers/network/BoardReachabilityFilter.java b/arduino-core/src/cc/arduino/packages/discoverers/network/BoardReachabilityFilter.java index c4c0ba52f..433142eb3 100644 --- a/arduino-core/src/cc/arduino/packages/discoverers/network/BoardReachabilityFilter.java +++ b/arduino-core/src/cc/arduino/packages/discoverers/network/BoardReachabilityFilter.java @@ -69,7 +69,7 @@ public class BoardReachabilityFilter extends TimerTask { ports.add(0, 22); } - boolean reachable = NetUtils.isReachable(inetAddress, ports); + boolean reachable = board.getPrefs().get("tcp_check").contentEquals("no") || NetUtils.isReachable(inetAddress, ports); if (!reachable) { boardPortIterator.remove(); } diff --git a/arduino-core/src/cc/arduino/packages/uploaders/GenericNetworkUploader.java b/arduino-core/src/cc/arduino/packages/uploaders/GenericNetworkUploader.java new file mode 100644 index 000000000..3a7cabf49 --- /dev/null +++ b/arduino-core/src/cc/arduino/packages/uploaders/GenericNetworkUploader.java @@ -0,0 +1,112 @@ +/* + GenericNetworkUploader - generic network uploader implementation + makes possible to implement firmware updates over the air on any device + Part of the Arduino project - http://www.arduino.cc/ + + Copyright (c) 2004-05 + Hernando Barragan + Copyright (c) 2012 + Cristian Maglie + Copyright (c) 2015 + Hristo Gochkov + + 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 2 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, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package cc.arduino.packages.uploaders; + +import cc.arduino.packages.BoardPort; +import cc.arduino.packages.Uploader; +import processing.app.*; +import processing.app.debug.RunnerException; +import processing.app.debug.TargetPlatform; +import processing.app.helpers.PreferencesMap; +import processing.app.helpers.StringReplacer; + +import java.io.File; +import java.util.List; + +import static processing.app.I18n.tr; + +public class GenericNetworkUploader extends Uploader { + + private final BoardPort port; + + public GenericNetworkUploader(BoardPort port) { + this.port = port; + } + + public boolean requiresAuthorization() { + return this.port.getPrefs().get("auth_upload").contentEquals("yes"); + } + + @Override + public String getAuthorizationKey() { + return "runtime.pwd." + this.port.getAddress(); + } + + public boolean uploadUsingPreferences(File sourcePath, String buildPath, String className, boolean usingProgrammer, List warningsAccumulator) throws Exception { + TargetPlatform targetPlatform = BaseNoGui.getTargetPlatform(); + PreferencesMap prefs = PreferencesData.getMap(); + PreferencesMap boardPreferences = BaseNoGui.getBoardPreferences(); + if (boardPreferences != null) { + prefs.putAll(boardPreferences); + } + String tool = prefs.getOrExcept("upload.tool"); + if (tool.contains(":")) { + String[] split = tool.split(":", 2); + targetPlatform = BaseNoGui.getCurrentTargetPlatformFromPackage(split[0]); + tool = split[1]; + } + prefs.putAll(targetPlatform.getTool(tool)); + + String password = ""; + if(requiresAuthorization()){ + password = prefs.getOrExcept(getAuthorizationKey()); + } + prefs.put("network.password", password); + + prefs.put("network.port", this.port.getPrefs().get("port")); + + prefs.put("build.path", buildPath); + prefs.put("build.project_name", className); + if (verbose) { + prefs.put("upload.verbose", prefs.getOrExcept("upload.params.verbose")); + } else { + prefs.put("upload.verbose", prefs.getOrExcept("upload.params.quiet")); + } + + boolean uploadResult; + try { + String pattern; + //check if there is a separate pattern for network uploads + pattern = prefs.get("upload.network_pattern"); + if(pattern == null) + pattern = prefs.getOrExcept("upload.pattern"); + String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true); + uploadResult = executeUploadCommand(cmd); + } catch (RunnerException e) { + throw e; + } catch (Exception e) { + throw new RunnerException(e); + } + return uploadResult; + } + + @Override + public boolean burnBootloader() throws RunnerException { + throw new RunnerException("Burning bootloader is not supported via network!"); + } +}