From d154120f0eafaa678032ca10b67cd5b203fe46d2 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 10 Mar 2020 17:11:09 +0100 Subject: [PATCH] Fix bogus port disconnection during serial event Fixes https://github.com/arduino/Arduino/issues/9785 and probably many others This commit strongly simplyfies the serial list code Pluggable discovery introduced a bug since BoardPort.toString() started reporting only the name of the port, not the complete name_vid_pid needed to match liblistserial output. Adding .toCompleteString() almost solves the bogus disconnection part alone, but resolveDeviceByVendorIdProductId() uses "0x" prefixes VID/PID, breaking it again. In addition, all the logic used to match a board with its bootloader (to obtain a serial number on 32u4 boards) has been completely removed since it is currently useless (and unused). --- .../src/cc/arduino/packages/BoardPort.java | 4 ++ .../discoverers/serial/SerialDiscovery.java | 47 +++++++------------ arduino-core/src/processing/app/Platform.java | 5 +- 3 files changed, 24 insertions(+), 32 deletions(-) diff --git a/arduino-core/src/cc/arduino/packages/BoardPort.java b/arduino-core/src/cc/arduino/packages/BoardPort.java index 2052339f1..397c0818a 100644 --- a/arduino-core/src/cc/arduino/packages/BoardPort.java +++ b/arduino-core/src/cc/arduino/packages/BoardPort.java @@ -122,6 +122,10 @@ public class BoardPort { return this.address; } + public String toCompleteString() { + return this.address + "_" + this.getPrefs().get("vid") + "_" + this.getPrefs().get("pid"); + } + // Search for the board which matches identificationPrefs. // If found, boardName is set to the name from boards.txt // and the board is returned. If not found, null is returned. diff --git a/arduino-core/src/cc/arduino/packages/discoverers/serial/SerialDiscovery.java b/arduino-core/src/cc/arduino/packages/discoverers/serial/SerialDiscovery.java index 7ce44f56b..3eade2aa0 100644 --- a/arduino-core/src/cc/arduino/packages/discoverers/serial/SerialDiscovery.java +++ b/arduino-core/src/cc/arduino/packages/discoverers/serial/SerialDiscovery.java @@ -46,7 +46,6 @@ public class SerialDiscovery implements Discovery, Runnable { private final List oldPorts = new ArrayList<>(); public boolean uploadInProgress = false; public boolean pausePolling = false; - private BoardPort oldUploadBoardPort = null; private final BoardCloudResolver boardCloudResolver = new BoardCloudResolver(); @@ -56,7 +55,7 @@ public class SerialDiscovery implements Discovery, Runnable { } @Override - public List listDiscoveredBoards(boolean complete) { + public synchronized List listDiscoveredBoards(boolean complete) { if (complete) { return new ArrayList<>(serialBoardPorts); } @@ -69,7 +68,7 @@ public class SerialDiscovery implements Discovery, Runnable { return onlineBoardPorts; } - public void setSerialBoardPorts(List newSerialBoardPorts) { + public synchronized void setSerialBoardPorts(List newSerialBoardPorts) { serialBoardPorts.clear(); serialBoardPorts.addAll(newSerialBoardPorts); } @@ -116,27 +115,17 @@ public class SerialDiscovery implements Discovery, Runnable { return; } - // if (updating) {} - // a port will disappear, another will appear - // use this information to "merge" the boards - // updating must be signaled by SerialUpload class - oldPorts.clear(); oldPorts.addAll(ports); + // set unreachable ports offline 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; - } + if (!ports.contains(board.toCompleteString())) { board.setOnlineStatus(false); } } + // add information for newly added ports for (String newPort : ports) { String[] parts = newPort.split("_"); @@ -161,35 +150,35 @@ public class SerialDiscovery implements Discovery, Runnable { BoardPort boardPort = null; int i = 0; - // create new board or update existing + + // create new board if in ports but not in boardPorts for (BoardPort board : boardPorts) { - if (board.toString().equals(newPort)) { + if (board.toCompleteString().equalsIgnoreCase(newPort)) { boardPort = boardPorts.get(i); + boardPorts.get(i).setOnlineStatus(true); break; } i++; } - if (boardPort == null) { - boardPort = new BoardPort(); - boardPorts.add(boardPort); + + if (boardPort != null) { + continue; } + + boardPort = new BoardPort(); + boardPorts.add(boardPort); boardPort.setAddress(port); boardPort.setProtocol("serial"); boardPort.setOnlineStatus(true); - String label = port; + boardPort.setLabel(port); if (boardData != null) { boardPort.getPrefs().put("vid", boardData.get("vid").toString()); boardPort.getPrefs().put("pid", boardData.get("pid").toString()); String iserial = boardData.get("iserial").toString(); - if (iserial.length() >= 10) { - boardPort.getPrefs().put("iserial", iserial); - } - if (uploadInProgress && oldUploadBoardPort!=null) { - oldUploadBoardPort.getPrefs().put("iserial", iserial); - } + boardPort.getPrefs().put("iserial", iserial); TargetBoard board = (TargetBoard) boardData.get("board"); if (board != null) { @@ -208,8 +197,6 @@ public class SerialDiscovery implements Discovery, Runnable { boardPort.getPrefs().put("iserial", ""); } } - - boardPort.setLabel(label); } setSerialBoardPorts(boardPorts); } diff --git a/arduino-core/src/processing/app/Platform.java b/arduino-core/src/processing/app/Platform.java index 2c02c37ed..913381316 100644 --- a/arduino-core/src/processing/app/Platform.java +++ b/arduino-core/src/processing/app/Platform.java @@ -202,8 +202,9 @@ public class Platform { } Map boardData = new HashMap<>(); boardData.put("board", board); - boardData.put("vid", vids.get(i)); - boardData.put("pid", pids.get(i)); + // remove 0x from VID / PID to keep them as reported by liblistserial + boardData.put("vid", vids.get(i).replaceAll("0x", "")); + boardData.put("pid", pids.get(i).replaceAll("0x", "")); String extrafields = vid_pid_iSerial.substring(vidPid.length() + 1); String[] parts = extrafields.split("_"); boardData.put("iserial", parts[0]);