diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 8da903bcb2f..d018b69b278 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -146,6 +146,8 @@ public boolean test(Sketch sketch) { private int numTools = 0; + public boolean avoidMultipleOperations = false; + private final EditorToolbar toolbar; // these menus are shared so that they needn't be rebuilt for all windows // each time a sketch is created, renamed, or moved. @@ -198,7 +200,7 @@ public boolean test(Sketch sketch) { private Runnable stopHandler; Runnable exportHandler; private Runnable exportAppHandler; - + private Runnable timeoutUploadHandler; public Editor(Base ibase, File file, int[] storedLocation, int[] defaultLocation, Platform platform) throws Exception { super("Arduino"); @@ -812,6 +814,9 @@ public void actionPerformed(ActionEvent e) { portMenu = new JMenu(tr("Port")); populatePortMenu(); toolsMenu.add(portMenu); + item = new JMenuItem(tr("Get Board Info")); + item.addActionListener(e -> handleBoardInfo()); + toolsMenu.add(item); toolsMenu.addSeparator(); base.rebuildProgrammerMenu(); @@ -1648,6 +1653,7 @@ private void resetHandlers() { stopHandler = new DefaultStopHandler(); exportHandler = new DefaultExportHandler(); exportAppHandler = new DefaultExportAppHandler(); + timeoutUploadHandler = new TimeoutUploadHandler(); } @@ -1979,6 +1985,7 @@ public void run() { status.unprogress(); toolbar.deactivateRun(); + avoidMultipleOperations = false; } } @@ -2367,6 +2374,7 @@ synchronized public void handleExport(final boolean usingProgrammer) { console.clear(); status.progress(tr("Uploading to I/O Board...")); + new Thread(timeoutUploadHandler).start(); new Thread(usingProgrammer ? exportAppHandler : exportHandler).start(); } @@ -2406,6 +2414,7 @@ public void run() { e.printStackTrace(); } finally { populatePortMenu(); + avoidMultipleOperations = false; } status.unprogress(); uploading = false; @@ -2433,13 +2442,14 @@ private void resumeOrCloseSerialMonitor() { } } try { - if (serialMonitor != null) - serialMonitor.resume(boardPort); - if (boardPort == null) { - serialMonitor.close(); - handleSerial(); - } else { + if (serialMonitor != null) { serialMonitor.resume(boardPort); + if (boardPort == null) { + serialMonitor.close(); + handleSerial(); + } else { + serialMonitor.resume(boardPort); + } } } catch (Exception e) { statusError(e); @@ -2500,6 +2510,7 @@ public void run() { } catch (Exception e) { e.printStackTrace(); } finally { + avoidMultipleOperations = false; populatePortMenu(); } status.unprogress(); @@ -2514,6 +2525,20 @@ public void run() { } } + class TimeoutUploadHandler implements Runnable { + + public void run() { + try { + //10 seconds, than reactivate upload functionality and let the programmer pid being killed + Thread.sleep(1000 * 10); + if (uploading) { + avoidMultipleOperations = false; + } + } catch (InterruptedException e) { + // noop + } + } + } public void handleSerial() { if(serialPlotter != null) { @@ -2558,7 +2583,7 @@ public void handleSerial() { // If currently uploading, disable the monitor (it will be later // enabled when done uploading) - if (uploading) { + if (uploading || avoidMultipleOperations) { try { serialMonitor.suspend(); } catch (Exception e) { @@ -2582,8 +2607,10 @@ public void handleSerial() { } try { - serialMonitor.open(); serialMonitor.setVisible(true); + if (!avoidMultipleOperations) { + serialMonitor.open(); + } success = true; } catch (ConnectException e) { statusError(tr("Unable to connect: is the sketch using the bridge?")); @@ -2730,6 +2757,59 @@ private void handleBurnBootloader() { }).start(); } + private void handleBoardInfo() { + console.clear(); + + String selectedPort = PreferencesData.get("serial.port"); + List ports = Base.getDiscoveryManager().discovery(); + + String label = ""; + String vid = ""; + String pid = ""; + String iserial = ""; + String protocol = ""; + boolean found = false; + + for (BoardPort port : ports) { + if (port.getAddress().equals(selectedPort)) { + label = port.getBoardName(); + vid = port.getVID(); + pid = port.getPID(); + iserial = port.getISerial(); + protocol = port.getProtocol(); + found = true; + break; + } + } + + if (!found) { + statusNotice(tr("Please select a port to obtain board info")); + return; + } + + if (protocol.equals("network")) { + statusNotice(tr("Network port, can't obtain info")); + return; + } + + if (vid == null || vid.equals("") || vid.equals("0000")) { + statusNotice(tr("Native serial port, can't obtain info")); + return; + } + + if (iserial == null || iserial.equals("")) { + iserial = tr("Upload any sketch to obtain it"); + } + + if (label == null) { + label = tr("Unknown board"); + } + + String infos = I18n.format("BN: {0}\nVID: {1}\nPID: {2}\nSN: {3}", label, vid, pid, iserial); + JTextArea textArea = new JTextArea(infos); + + JOptionPane.showMessageDialog(this, textArea, tr("Board Info"), JOptionPane.PLAIN_MESSAGE); + } /** * Handler for File → Page Setup. diff --git a/app/src/processing/app/EditorLineStatus.java b/app/src/processing/app/EditorLineStatus.java index b68b74b4674..506e8f56d71 100644 --- a/app/src/processing/app/EditorLineStatus.java +++ b/app/src/processing/app/EditorLineStatus.java @@ -52,6 +52,7 @@ public class EditorLineStatus extends JComponent { String text = ""; String name = ""; String serialport = ""; + String serialnumber = ""; public EditorLineStatus() { background = Theme.getColor("linestatus.bgcolor"); @@ -129,6 +130,10 @@ public void setSerialPort(String serialport) { this.serialport = serialport; } + public void setSerialNumber(String serialnumber) { + this.serialnumber = serialnumber; + } + public Dimension getPreferredSize() { return scale(new Dimension(300, height)); } diff --git a/app/src/processing/app/EditorToolbar.java b/app/src/processing/app/EditorToolbar.java index a6b8bce6047..a4d18b5f72d 100644 --- a/app/src/processing/app/EditorToolbar.java +++ b/app/src/processing/app/EditorToolbar.java @@ -341,7 +341,10 @@ public void mousePressed(MouseEvent e) { switch (sel) { case RUN: - editor.handleRun(false, editor.presentHandler, editor.runHandler); + if (!editor.avoidMultipleOperations) { + editor.handleRun(false, editor.presentHandler, editor.runHandler); + editor.avoidMultipleOperations = true; + } break; // case STOP: @@ -370,7 +373,11 @@ public void mousePressed(MouseEvent e) { break; case EXPORT: - editor.handleExport(e.isShiftDown()); + // launch a timeout timer which can reenable to upload button functionality an + if (!editor.avoidMultipleOperations) { + editor.handleExport(e.isShiftDown()); + editor.avoidMultipleOperations = true; + } break; case SERIAL: diff --git a/arduino-core/src/cc/arduino/packages/BoardPort.java b/arduino-core/src/cc/arduino/packages/BoardPort.java index e2c16c43e69..0e85ffe135d 100644 --- a/arduino-core/src/cc/arduino/packages/BoardPort.java +++ b/arduino-core/src/cc/arduino/packages/BoardPort.java @@ -36,8 +36,12 @@ public class BoardPort { private String address; private String protocol; private String boardName; + private String vid; + private String pid; + private String iserial; private String label; private final PreferencesMap prefs; + private boolean online; public BoardPort() { this.prefs = new PreferencesMap(); @@ -79,4 +83,36 @@ public String getLabel() { return label; } + public void setOnlineStatus(boolean online) { + this.online = online; + } + + public boolean isOnline() { + return online; + } + + public void setVIDPID(String vid, String pid) { + this.vid = vid; + this.pid = pid; + } + + public String getVID() { + return vid; + } + + public String getPID() { + return pid; + } + + public void setISerial(String iserial) { + this.iserial = iserial; + } + public String getISerial() { + return iserial; + } + + @Override + public String toString() { + return this.address+"_"+this.vid+"_"+this.pid; + } } diff --git a/arduino-core/src/cc/arduino/packages/Discovery.java b/arduino-core/src/cc/arduino/packages/Discovery.java index eb4b41da2b1..911fcc2f6f5 100644 --- a/arduino-core/src/cc/arduino/packages/Discovery.java +++ b/arduino-core/src/cc/arduino/packages/Discovery.java @@ -51,5 +51,6 @@ public interface Discovery { * @return */ List listDiscoveredBoards(); + List listDiscoveredBoards(boolean complete); } diff --git a/arduino-core/src/cc/arduino/packages/DiscoveryManager.java b/arduino-core/src/cc/arduino/packages/DiscoveryManager.java index add7d0671e6..2632386d47e 100644 --- a/arduino-core/src/cc/arduino/packages/DiscoveryManager.java +++ b/arduino-core/src/cc/arduino/packages/DiscoveryManager.java @@ -40,11 +40,13 @@ public class DiscoveryManager { private final List discoverers; + private final SerialDiscovery serialDiscoverer = new SerialDiscovery(); + private final NetworkDiscovery networkDiscoverer = new NetworkDiscovery(); public DiscoveryManager() { discoverers = new ArrayList(); - discoverers.add(new SerialDiscovery()); - discoverers.add(new NetworkDiscovery()); + discoverers.add(serialDiscoverer); + discoverers.add(networkDiscoverer); // Start all discoverers for (Discovery d : discoverers) { @@ -69,6 +71,10 @@ public DiscoveryManager() { Runtime.getRuntime().addShutdownHook(closeHook); } + public SerialDiscovery getSerialDiscoverer() { + return serialDiscoverer; + } + public List discovery() { List res = new ArrayList(); for (Discovery d : discoverers) { @@ -77,6 +83,14 @@ public List discovery() { return res; } + public List discovery(boolean complete) { + List res = new ArrayList(); + for (Discovery d : discoverers) { + res.addAll(d.listDiscoveredBoards(complete)); + } + return res; + } + public BoardPort find(String address) { for (BoardPort boardPort : discovery()) { if (boardPort.getAddress().equals(address)) { @@ -86,4 +100,13 @@ public BoardPort find(String address) { return null; } + public BoardPort find(String address, boolean complete) { + for (BoardPort boardPort : discovery(complete)) { + if (boardPort.getAddress().equals(address)) { + return boardPort; + } + } + return null; + } + } diff --git a/arduino-core/src/cc/arduino/packages/Uploader.java b/arduino-core/src/cc/arduino/packages/Uploader.java index d58d29504f5..cd9a11a4521 100644 --- a/arduino-core/src/cc/arduino/packages/Uploader.java +++ b/arduino-core/src/cc/arduino/packages/Uploader.java @@ -44,6 +44,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.TimeUnit; import static processing.app.I18n.tr; @@ -102,6 +103,9 @@ public String getAuthorizationKey() { return null; } + // static field for last executed programmer process ID + static protected Process programmerPid; + protected boolean executeUploadCommand(Collection command) throws Exception { return executeUploadCommand(command.toArray(new String[command.size()])); } @@ -121,11 +125,20 @@ protected boolean executeUploadCommand(String command[]) throws Exception { System.out.println(); } Process process = ProcessUtils.exec(command); + programmerPid = process; new MessageSiphon(process.getInputStream(), this, 100); new MessageSiphon(process.getErrorStream(), this, 100); - // wait for the process to finish. - result = process.waitFor(); + // wait for the process to finish, but not forever + // kill the flasher process after 2 minutes to avoid 100% cpu spinning + if (!process.waitFor(2, TimeUnit.MINUTES)) { + process.destroyForcibly(); + } + if (!process.isAlive()) { + result = process.exitValue(); + } else { + result = 0; + } } catch (Exception e) { e.printStackTrace(); } diff --git a/arduino-core/src/cc/arduino/packages/discoverers/NetworkDiscovery.java b/arduino-core/src/cc/arduino/packages/discoverers/NetworkDiscovery.java index ebbb8c50df1..e88568a1e42 100644 --- a/arduino-core/src/cc/arduino/packages/discoverers/NetworkDiscovery.java +++ b/arduino-core/src/cc/arduino/packages/discoverers/NetworkDiscovery.java @@ -67,6 +67,13 @@ public List listDiscoveredBoards() { } } + @Override + public List listDiscoveredBoards(boolean complete) { + synchronized (reachableBoardPorts) { + return new LinkedList<>(reachableBoardPorts); + } + } + public void setReachableBoardPorts(List newReachableBoardPorts) { synchronized (reachableBoardPorts) { this.reachableBoardPorts.clear(); diff --git a/arduino-core/src/cc/arduino/packages/discoverers/SerialDiscovery.java b/arduino-core/src/cc/arduino/packages/discoverers/SerialDiscovery.java index 9c3efdc5200..3e6646d6732 100644 --- a/arduino-core/src/cc/arduino/packages/discoverers/SerialDiscovery.java +++ b/arduino-core/src/cc/arduino/packages/discoverers/SerialDiscovery.java @@ -41,6 +41,7 @@ public class SerialDiscovery implements Discovery { private Timer serialBoardsListerTimer; private final List serialBoardPorts; + private SerialBoardsLister serialBoardsLister = new SerialBoardsLister(this);; public SerialDiscovery() { this.serialBoardPorts = new LinkedList<>(); @@ -48,26 +49,45 @@ public SerialDiscovery() { @Override public List listDiscoveredBoards() { - return getSerialBoardPorts(); + return getSerialBoardPorts(false); } - private List getSerialBoardPorts() { - synchronized (serialBoardPorts) { - return new LinkedList<>(serialBoardPorts); - } + public List listDiscoveredBoards(boolean complete) { + return getSerialBoardPorts(complete); + } + + private List getSerialBoardPorts(boolean complete) { + if (complete) { + return new LinkedList<>(serialBoardPorts); + } + List onlineBoardPorts = new LinkedList<>(); + for (BoardPort port : serialBoardPorts) { + if (port.isOnline() == true) { + onlineBoardPorts.add(port); + } + } + return onlineBoardPorts; } public void setSerialBoardPorts(List newSerialBoardPorts) { - synchronized (serialBoardPorts) { serialBoardPorts.clear(); serialBoardPorts.addAll(newSerialBoardPorts); - } } + public void forceRefresh() { + serialBoardsLister.retriggerDiscovery(false); + } + + public void setUploadInProgress(boolean param) { + serialBoardsLister.uploadInProgress = param; + } + + public void pausePolling(boolean param) { serialBoardsLister.pausePolling = param;} + @Override public void start() { this.serialBoardsListerTimer = new Timer(SerialBoardsLister.class.getName()); - new SerialBoardsLister(this).start(serialBoardsListerTimer); + serialBoardsLister.start(serialBoardsListerTimer); } @Override diff --git a/arduino-core/src/cc/arduino/packages/discoverers/serial/SerialBoardsLister.java b/arduino-core/src/cc/arduino/packages/discoverers/serial/SerialBoardsLister.java index 5ca99819b89..77d2922e7a2 100644 --- a/arduino-core/src/cc/arduino/packages/discoverers/serial/SerialBoardsLister.java +++ b/arduino-core/src/cc/arduino/packages/discoverers/serial/SerialBoardsLister.java @@ -31,9 +31,9 @@ import cc.arduino.packages.BoardPort; import cc.arduino.packages.discoverers.SerialDiscovery; +import cc.arduino.packages.uploaders.SerialUploader; import processing.app.BaseNoGui; import processing.app.Platform; -import processing.app.Serial; import processing.app.debug.TargetBoard; import java.util.*; @@ -41,6 +41,11 @@ public class SerialBoardsLister extends TimerTask { private final SerialDiscovery serialDiscovery; + private final List boardPorts = new LinkedList<>(); + private List oldPorts = new LinkedList<>(); + public boolean uploadInProgress = false; + public boolean pausePolling = false; + private BoardPort oldUploadBoardPort = null; public SerialBoardsLister(SerialDiscovery serialDiscovery) { this.serialDiscovery = serialDiscovery; @@ -50,43 +55,89 @@ public void start(Timer timer) { timer.schedule(this, 0, 1000); } - @Override - public void run() { - while (BaseNoGui.packages == null) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // noop - } - } - + public synchronized void retriggerDiscovery(boolean polled) { Platform platform = BaseNoGui.getPlatform(); if (platform == null) { return; } - List boardPorts = new LinkedList<>(); + if (polled && pausePolling) { + return; + } + + List ports = platform.listSerials(); + if (ports.equals(oldPorts)) { + return; + } - List ports = Serial.list(); + // if (updating) {} + // a port will disappear, another will appear + // use this information to "merge" the boards + // updating must be signaled by SerialUpload class - String devicesListOutput = null; - if (!ports.isEmpty()) { - devicesListOutput = platform.preListAllCandidateDevices(); + oldPorts.clear(); + oldPorts.addAll(ports); + + for (BoardPort board : boardPorts) { + if (ports.contains(board.toString())) { + if (board.isOnline()) { + ports.remove(ports.indexOf(board.toString())); + } + } else { + if (uploadInProgress && board.isOnline()) { + oldUploadBoardPort = board; + } + board.setOnlineStatus(false); + } } - for (String port : ports) { - Map boardData = platform.resolveDeviceByVendorIdProductId(port, BaseNoGui.packages, devicesListOutput); + for (String newPort : ports) { - BoardPort boardPort = new BoardPort(); + String[] parts = newPort.split("_"); + String port = parts[0]; + + if (parts.length != 3) { + // something went horribly wrong + continue; + } + + Map boardData = platform.resolveDeviceByVendorIdProductId(port, BaseNoGui.packages); + + BoardPort boardPort = null; + boolean updatingInfos = false; + int i = 0; + // create new board or update existing + for (BoardPort board : boardPorts) { + if (board.toString().equals(newPort)) { + updatingInfos = true; + boardPort = boardPorts.get(i); + break; + } + i++; + } + if (!updatingInfos) { + boardPort = new BoardPort(); + } boardPort.setAddress(port); boardPort.setProtocol("serial"); + boardPort.setOnlineStatus(true); String label = port; if (boardData != null) { boardPort.getPrefs().put("vid", boardData.get("vid").toString()); boardPort.getPrefs().put("pid", boardData.get("pid").toString()); - boardPort.getPrefs().put("iserial", boardData.get("iserial").toString()); + boardPort.setVIDPID(parts[1], parts[2]); + + String iserial = boardData.get("iserial").toString(); + if (iserial.length() >= 10) { + boardPort.getPrefs().put("iserial", iserial); + boardPort.setISerial(iserial); + } + if (uploadInProgress && oldUploadBoardPort!=null) { + oldUploadBoardPort.getPrefs().put("iserial", iserial); + oldUploadBoardPort.setISerial(iserial); + } TargetBoard board = (TargetBoard) boardData.get("board"); if (board != null) { @@ -96,13 +147,28 @@ public void run() { } boardPort.setBoardName(boardName); } + } else { + if (parts[1] != "0000") { + boardPort.setVIDPID(parts[1], parts[2]); + } else { + boardPort.setVIDPID("0000", "0000"); + boardPort.setISerial(""); + } } boardPort.setLabel(label); - - boardPorts.add(boardPort); + if (!updatingInfos) { + boardPorts.add(boardPort); + } } - serialDiscovery.setSerialBoardPorts(boardPorts); } + + @Override + public void run() { + if (BaseNoGui.packages == null) { + return; + } + retriggerDiscovery(true); + } } diff --git a/arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java b/arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java index 971bfb8c6f9..a850e23f762 100644 --- a/arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java +++ b/arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java @@ -44,6 +44,8 @@ import processing.app.helpers.PreferencesMap; import processing.app.helpers.StringReplacer; +import cc.arduino.packages.discoverers.SerialDiscovery; + import java.io.File; import java.util.ArrayList; import java.util.List; @@ -78,12 +80,19 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String } prefs.putAll(targetPlatform.getTool(tool)); + if (programmerPid != null && programmerPid.isAlive()) { + // kill the previous programmer + programmerPid.destroyForcibly(); + } + // if no protocol is specified for this board, assume it lacks a // bootloader and upload using the selected programmer. if (usingProgrammer || prefs.get("upload.protocol") == null) { return uploadUsingProgrammer(buildPath, className); } + BaseNoGui.getDiscoveryManager().getSerialDiscoverer().pausePolling(true); + if (noUploadPort) { prefs.put("build.path", buildPath); @@ -100,6 +109,8 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String uploadResult = executeUploadCommand(cmd); } catch (Exception e) { throw new RunnerException(e); + } finally { + BaseNoGui.getDiscoveryManager().getSerialDiscoverer().pausePolling(false); } return uploadResult; } @@ -134,13 +145,15 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String // Scanning for available ports seems to open the port or // otherwise assert DTR, which would cancel the WDT reset if // it happened within 250 ms. So we wait until the reset should - // have already occured before we start scanning. + // have already occurred before we start scanning. actualUploadPort = waitForUploadPort(userSelectedUploadPort, before); } } catch (SerialException e) { throw new RunnerException(e); } catch (InterruptedException e) { throw new RunnerException(e.getMessage()); + } finally { + BaseNoGui.getDiscoveryManager().getSerialDiscoverer().pausePolling(false); } if (actualUploadPort == null) { actualUploadPort = userSelectedUploadPort; @@ -151,13 +164,12 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String } else { prefs.put("serial.port.file", actualUploadPort); } - } - BoardPort boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port")); - try { - prefs.put("serial.port.iserial", boardPort.getPrefs().getOrExcept("iserial")); - } catch (Exception e) { - // if serial port does not contain an iserial field + // retrigger a discovery + BaseNoGui.getDiscoveryManager().getSerialDiscoverer().setUploadInProgress(true); + Thread.sleep(100); + BaseNoGui.getDiscoveryManager().getSerialDiscoverer().forceRefresh(); + Thread.sleep(100); } prefs.put("build.path", buildPath); @@ -177,8 +189,13 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String throw e; } catch (Exception e) { throw new RunnerException(e); + } finally { + BaseNoGui.getDiscoveryManager().getSerialDiscoverer().pausePolling(false); } + BaseNoGui.getDiscoveryManager().getSerialDiscoverer().setUploadInProgress(false); + BaseNoGui.getDiscoveryManager().getSerialDiscoverer().pausePolling(false); + String finalUploadPort = null; if (uploadResult && doTouch) { try { @@ -191,10 +208,7 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String long started = System.currentTimeMillis(); while (System.currentTimeMillis() - started < 2000) { List portList = Serial.list(); - if (portList.contains(actualUploadPort)) { - finalUploadPort = actualUploadPort; - break; - } else if (portList.contains(userSelectedUploadPort)) { + if (portList.contains(userSelectedUploadPort)) { finalUploadPort = userSelectedUploadPort; break; } @@ -213,6 +227,7 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String finalUploadPort = userSelectedUploadPort; } BaseNoGui.selectSerialPort(finalUploadPort); + return uploadResult; } diff --git a/arduino-core/src/processing/app/BaseNoGui.java b/arduino-core/src/processing/app/BaseNoGui.java index a2eab2559d6..a431a19d7ec 100644 --- a/arduino-core/src/processing/app/BaseNoGui.java +++ b/arduino-core/src/processing/app/BaseNoGui.java @@ -33,6 +33,8 @@ import java.util.logging.Level; import java.util.logging.Logger; +import cc.arduino.packages.BoardPort; + import static processing.app.I18n.tr; import static processing.app.helpers.filefilters.OnlyDirs.ONLY_DIRS; @@ -1119,6 +1121,10 @@ static public void selectBoard(TargetBoard targetBoard) { public static void selectSerialPort(String port) { PreferencesData.set("serial.port", port); + BoardPort boardPort = getDiscoveryManager().find(port, true); + if (boardPort != null) { + PreferencesData.set("serial.port.iserial", boardPort.getPrefs().get("iserial")); + } String portFile = port; if (port.startsWith("/dev/")) { portFile = portFile.substring(5); diff --git a/arduino-core/src/processing/app/Platform.java b/arduino-core/src/processing/app/Platform.java index 29e5e733d87..0c2c1d8cbbd 100644 --- a/arduino-core/src/processing/app/Platform.java +++ b/arduino-core/src/processing/app/Platform.java @@ -35,6 +35,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.ArrayList; +import java.util.Arrays; import static processing.app.I18n.tr; @@ -160,13 +162,26 @@ private static void loadLib(File lib) { } } - public native String resolveDeviceAttachedToNative(String serial); + private native String resolveDeviceAttachedToNative(String serial); + private native String[] listSerialsNative(); public String preListAllCandidateDevices() { return null; } - public Map resolveDeviceByVendorIdProductId(String serial, Map packages, String devicesListOutput) { + public List listSerials(){ + return new ArrayList(Arrays.asList(this.listSerialsNative())); + } + + public List listSerialsNames(){ + List list = new LinkedList<>(); + for (String port : this.listSerialsNative()) { + list.add(port.split("_")[0]); + } + return list; + } + + public synchronized Map resolveDeviceByVendorIdProductId(String serial, Map packages) { String vid_pid_iSerial = resolveDeviceAttachedToNative(serial); for (TargetPackage targetPackage : packages.values()) { for (TargetPlatform targetPlatform : targetPackage.getPlatforms().values()) { diff --git a/arduino-core/src/processing/app/helpers/StringReplacer.java b/arduino-core/src/processing/app/helpers/StringReplacer.java index f51bfd7b696..fae77155aef 100644 --- a/arduino-core/src/processing/app/helpers/StringReplacer.java +++ b/arduino-core/src/processing/app/helpers/StringReplacer.java @@ -94,7 +94,9 @@ public static String replaceFromMapping(String src, Map map, String rightDelimiter) { for (Map.Entry entry : map.entrySet()) { String keyword = leftDelimiter + entry.getKey() + rightDelimiter; - src = src.replace(keyword, entry.getValue()); + if (entry.getValue() != null && keyword != null) { + src = src.replace(keyword, entry.getValue()); + } } return src; } diff --git a/build/build.xml b/build/build.xml index 43464da190c..444c6502bff 100644 --- a/build/build.xml +++ b/build/build.xml @@ -78,6 +78,7 @@ + @@ -436,12 +437,12 @@ - - - + + + - + @@ -639,12 +640,12 @@ - - - + + + - + @@ -908,12 +909,12 @@ - - - + + + - + diff --git a/build/liblistSerials-1.0.5.zip.sha b/build/liblistSerials-1.0.5.zip.sha deleted file mode 100644 index 6484b2fbc08..00000000000 --- a/build/liblistSerials-1.0.5.zip.sha +++ /dev/null @@ -1 +0,0 @@ -edb1c858a243e465f5797d7e5d0baa66daa1eba0 diff --git a/build/liblistSerials-1.1.0.zip.sha b/build/liblistSerials-1.1.0.zip.sha new file mode 100644 index 00000000000..f4bc4a9a239 --- /dev/null +++ b/build/liblistSerials-1.1.0.zip.sha @@ -0,0 +1 @@ +05e942bc85e46a2b59e01fe1333dd9472e465654