Skip to content

Commit 0e45f4e

Browse files
authored
Merge pull request #8038 from cmaglie/pluggable-discovery
Pluggable discovery: search in platform.txt (WIP)
2 parents 4ae2e1f + d4bbf71 commit 0e45f4e

14 files changed

+631
-232
lines changed

app/src/processing/app/Base.java

+2
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ public Base(String[] args) throws Exception {
267267
splash.splashText(tr("Initializing packages..."));
268268
BaseNoGui.initPackages();
269269

270+
parser.getUploadPort().ifPresent(BaseNoGui::selectSerialPort);
271+
270272
splash.splashText(tr("Preparing boards..."));
271273

272274
if (!isCommandLine()) {

app/src/processing/app/Editor.java

+50-33
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
import java.util.ArrayList;
5353
import java.util.Arrays;
5454
import java.util.Collections;
55-
import java.util.Comparator;
5655
import java.util.Enumeration;
5756
import java.util.HashMap;
5857
import java.util.LinkedList;
@@ -96,6 +95,7 @@
9695
import cc.arduino.view.findreplace.FindReplace;
9796
import jssc.SerialPortException;
9897
import processing.app.debug.RunnerException;
98+
import processing.app.debug.TargetBoard;
9999
import processing.app.forms.PasswordAuthorizationDialog;
100100
import processing.app.helpers.DocumentTextChangeListener;
101101
import processing.app.helpers.Keys;
@@ -149,9 +149,6 @@ public boolean test(SketchController controller) {
149149
}
150150
}
151151

152-
private final static List<String> BOARD_PROTOCOLS_ORDER = Arrays.asList("serial", "network");
153-
private final static List<String> BOARD_PROTOCOLS_ORDER_TRANSLATIONS = Arrays.asList(tr("Serial ports"), tr("Network ports"));
154-
155152
final Base base;
156153

157154
// otherwise, if the window is resized with the message label
@@ -1043,22 +1040,30 @@ class BoardPortJCheckBoxMenuItem extends JCheckBoxMenuItem {
10431040
private BoardPort port;
10441041

10451042
public BoardPortJCheckBoxMenuItem(BoardPort port) {
1046-
super(port.getLabel());
1043+
super();
1044+
this.port = port;
1045+
setText(toString());
10471046
addActionListener(e -> {
10481047
selectSerialPort(port.getAddress());
10491048
base.onBoardOrPortChange();
10501049
});
1051-
this.port = port;
10521050
}
10531051

10541052
@Override
10551053
public String toString() {
10561054
// This is required for serialPrompt()
1057-
return port.getLabel();
1055+
String label = port.getLabel();
1056+
if (port.getBoardName() != null && !port.getBoardName().isEmpty()) {
1057+
label += " (" + port.getBoardName() + ")";
1058+
}
1059+
return label;
10581060
}
10591061
}
10601062

10611063
private void populatePortMenu() {
1064+
final List<String> PROTOCOLS_ORDER = Arrays.asList("serial", "network");
1065+
final List<String> PROTOCOLS_LABELS = Arrays.asList(tr("Serial ports"), tr("Network ports"));
1066+
10621067
portMenu.removeAll();
10631068

10641069
String selectedPort = PreferencesData.get("serial.port");
@@ -1067,31 +1072,43 @@ private void populatePortMenu() {
10671072

10681073
ports = platform.filterPorts(ports, PreferencesData.getBoolean("serial.ports.showall"));
10691074

1070-
Collections.sort(ports, new Comparator<BoardPort>() {
1071-
@Override
1072-
public int compare(BoardPort o1, BoardPort o2) {
1073-
return (BOARD_PROTOCOLS_ORDER.indexOf(o1.getProtocol()) - BOARD_PROTOCOLS_ORDER.indexOf(o2.getProtocol())) * 10 +
1074-
o1.getAddress().compareTo(o2.getAddress());
1075-
}
1075+
ports.stream() //
1076+
.filter(port -> port.getProtocolLabel() == null || port.getProtocolLabel().isEmpty())
1077+
.forEach(port -> {
1078+
int labelIdx = PROTOCOLS_ORDER.indexOf(port.getProtocol());
1079+
if (labelIdx != -1) {
1080+
port.setProtocolLabel(PROTOCOLS_LABELS.get(labelIdx));
1081+
} else {
1082+
port.setProtocolLabel(port.getProtocol());
1083+
}
1084+
});
1085+
1086+
Collections.sort(ports, (port1, port2) -> {
1087+
String pr1 = port1.getProtocol();
1088+
String pr2 = port2.getProtocol();
1089+
int prIdx1 = PROTOCOLS_ORDER.contains(pr1) ? PROTOCOLS_ORDER.indexOf(pr1) : 999;
1090+
int prIdx2 = PROTOCOLS_ORDER.contains(pr2) ? PROTOCOLS_ORDER.indexOf(pr2) : 999;
1091+
int r = prIdx1 - prIdx2;
1092+
if (r != 0)
1093+
return r;
1094+
r = port1.getProtocolLabel().compareTo(port2.getProtocolLabel());
1095+
if (r != 0)
1096+
return r;
1097+
return port1.getAddress().compareTo(port2.getAddress());
10761098
});
10771099

1078-
String lastProtocol = null;
1079-
String lastProtocolTranslated;
1100+
String lastProtocol = "";
1101+
String lastProtocolLabel = "";
10801102
for (BoardPort port : ports) {
1081-
if (lastProtocol == null || !port.getProtocol().equals(lastProtocol)) {
1082-
if (lastProtocol != null) {
1103+
if (!port.getProtocol().equals(lastProtocol) || !port.getProtocolLabel().equals(lastProtocolLabel)) {
1104+
if (!lastProtocol.isEmpty()) {
10831105
portMenu.addSeparator();
10841106
}
10851107
lastProtocol = port.getProtocol();
1086-
1087-
if (BOARD_PROTOCOLS_ORDER.indexOf(port.getProtocol()) != -1) {
1088-
lastProtocolTranslated = BOARD_PROTOCOLS_ORDER_TRANSLATIONS.get(BOARD_PROTOCOLS_ORDER.indexOf(port.getProtocol()));
1089-
} else {
1090-
lastProtocolTranslated = port.getProtocol();
1091-
}
1092-
JMenuItem lastProtocolMenuItem = new JMenuItem(tr(lastProtocolTranslated));
1093-
lastProtocolMenuItem.setEnabled(false);
1094-
portMenu.add(lastProtocolMenuItem);
1108+
lastProtocolLabel = port.getProtocolLabel();
1109+
JMenuItem item = new JMenuItem(tr(lastProtocolLabel));
1110+
item.setEnabled(false);
1111+
portMenu.add(item);
10951112
}
10961113
String address = port.getAddress();
10971114

@@ -2403,9 +2420,9 @@ private void handleBoardInfo() {
24032420
for (BoardPort port : ports) {
24042421
if (port.getAddress().equals(selectedPort)) {
24052422
label = port.getBoardName();
2406-
vid = port.getVID();
2407-
pid = port.getPID();
2408-
iserial = port.getISerial();
2423+
vid = port.getPrefs().get("vid");
2424+
pid = port.getPrefs().get("pid");
2425+
iserial = port.getPrefs().get("iserial");
24092426
protocol = port.getProtocol();
24102427
found = true;
24112428
break;
@@ -2575,12 +2592,12 @@ private void statusEmpty() {
25752592
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25762593

25772594
protected void onBoardOrPortChange() {
2578-
Map<String, String> boardPreferences = BaseNoGui.getBoardPreferences();
2579-
if (boardPreferences != null)
2580-
lineStatus.setBoardName(boardPreferences.get("name"));
2595+
TargetBoard board = BaseNoGui.getTargetBoard();
2596+
if (board != null)
2597+
lineStatus.setBoardName(board.getName());
25812598
else
25822599
lineStatus.setBoardName("-");
2583-
lineStatus.setSerialPort(PreferencesData.get("serial.port"));
2600+
lineStatus.setPort(PreferencesData.get("serial.port"));
25842601
lineStatus.repaint();
25852602
}
25862603

app/src/processing/app/EditorLineStatus.java

+7-12
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ public class EditorLineStatus extends JComponent {
5151

5252
String text = "";
5353
String name = "";
54-
String serialport = "";
55-
String serialnumber = "";
54+
String port = "";
5655

5756
public EditorLineStatus() {
5857
background = Theme.getColor("linestatus.bgcolor");
@@ -92,13 +91,13 @@ public void set(int newStart, int newStop) {
9291

9392
public void paintComponent(Graphics graphics) {
9493
Graphics2D g = Theme.setupGraphics2D(graphics);
95-
if (name.isEmpty() && serialport.isEmpty()) {
94+
if (name.isEmpty() && port.isEmpty()) {
9695
PreferencesMap boardPreferences = BaseNoGui.getBoardPreferences();
9796
if (boardPreferences != null)
9897
setBoardName(boardPreferences.get("name"));
9998
else
10099
setBoardName("-");
101-
setSerialPort(PreferencesData.get("serial.port"));
100+
setPort(PreferencesData.get("serial.port"));
102101
}
103102
g.setColor(background);
104103
Dimension size = getSize();
@@ -112,8 +111,8 @@ public void paintComponent(Graphics graphics) {
112111
g.setColor(messageForeground);
113112

114113
String statusText;
115-
if (serialport != null && !serialport.isEmpty()) {
116-
statusText = I18n.format(tr("{0} on {1}"), name, serialport);
114+
if (port != null && !port.isEmpty()) {
115+
statusText = I18n.format(tr("{0} on {1}"), name, port);
117116
} else {
118117
statusText = name;
119118
}
@@ -132,12 +131,8 @@ public void setBoardName(String name) {
132131
this.name = name;
133132
}
134133

135-
public void setSerialPort(String serialport) {
136-
this.serialport = serialport;
137-
}
138-
139-
public void setSerialNumber(String serialnumber) {
140-
this.serialnumber = serialnumber;
134+
public void setPort(String port) {
135+
this.port = port;
141136
}
142137

143138
public Dimension getPreferredSize() {

arduino-core/src/cc/arduino/packages/BoardPort.java

+103-29
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,36 @@
2929

3030
package cc.arduino.packages;
3131

32+
import processing.app.BaseNoGui;
33+
import processing.app.debug.TargetBoard;
34+
import processing.app.debug.TargetPackage;
35+
import processing.app.debug.TargetPlatform;
3236
import processing.app.helpers.PreferencesMap;
3337

3438
public class BoardPort {
3539

36-
private String address;
37-
private String protocol;
40+
private String address; // unique name for this port, used by Preferences
41+
private String protocol; // how to communicate, used for Ports menu sections
42+
private String protocolLabel; // protocol extended name to display on GUI
3843
private String boardName;
39-
private String vid;
40-
private String pid;
41-
private String iserial;
42-
private String label;
43-
private final PreferencesMap prefs;
44-
private boolean online;
44+
private String label; // friendly name shown in Ports menu
45+
private final PreferencesMap identificationPrefs; // data to match with boards.txt
46+
private final PreferencesMap prefs; // "vendorId", "productId", "serialNumber"
47+
private boolean online; // used by SerialBoardsLister (during upload??)
4548

4649
public BoardPort() {
4750
this.prefs = new PreferencesMap();
51+
this.identificationPrefs = new PreferencesMap();
52+
}
53+
54+
public BoardPort(BoardPort bp) {
55+
prefs = new PreferencesMap(bp.prefs);
56+
identificationPrefs = new PreferencesMap(bp.identificationPrefs);
57+
address = bp.address;
58+
protocol = bp.protocol;
59+
boardName = bp.boardName;
60+
label = bp.label;
61+
online = bp.online;
4862
}
4963

5064
public String getAddress() {
@@ -63,6 +77,14 @@ public void setProtocol(String protocol) {
6377
this.protocol = protocol;
6478
}
6579

80+
public String getProtocolLabel() {
81+
return protocolLabel;
82+
}
83+
84+
public void setProtocolLabel(String protocolLabel) {
85+
this.protocolLabel = protocolLabel;
86+
}
87+
6688
public String getBoardName() {
6789
return boardName;
6890
}
@@ -75,6 +97,10 @@ public PreferencesMap getPrefs() {
7597
return prefs;
7698
}
7799

100+
public PreferencesMap getIdentificationPrefs() {
101+
return identificationPrefs;
102+
}
103+
78104
public void setLabel(String label) {
79105
this.label = label;
80106
}
@@ -91,28 +117,76 @@ public boolean isOnline() {
91117
return online;
92118
}
93119

94-
public void setVIDPID(String vid, String pid) {
95-
this.vid = vid;
96-
this.pid = pid;
97-
}
98-
99-
public String getVID() {
100-
return vid;
101-
}
102-
103-
public String getPID() {
104-
return pid;
105-
}
106-
107-
public void setISerial(String iserial) {
108-
this.iserial = iserial;
109-
}
110-
public String getISerial() {
111-
return iserial;
112-
}
113-
114120
@Override
115121
public String toString() {
116-
return this.address+"_"+this.vid+"_"+this.pid;
122+
return this.address;
123+
}
124+
125+
// Search for the board which matches identificationPrefs.
126+
// If found, boardName is set to the name from boards.txt
127+
// and the board is returned. If not found, null is returned.
128+
public TargetBoard searchMatchingBoard() {
129+
if (identificationPrefs == null || identificationPrefs.isEmpty()) return null;
130+
for (TargetPackage targetPackage : BaseNoGui.packages.values()) {
131+
for (TargetPlatform targetPlatform : targetPackage.getPlatforms().values()) {
132+
for (TargetBoard board : targetPlatform.getBoards().values()) {
133+
if (matchesBoard(board)) {
134+
setBoardName(board.getName());
135+
return board;
136+
}
137+
}
138+
}
139+
}
140+
return null;
141+
}
142+
143+
public boolean matchesBoard(TargetBoard board) {
144+
PreferencesMap identificationProps = getIdentificationPrefs();
145+
PreferencesMap boardProps = board.getPreferences();
146+
147+
String wildMatcher = identificationProps.get(".");
148+
if (wildMatcher != null) {
149+
if (wildMatcher.equals(board.getId())) {
150+
return true;
151+
}
152+
if (wildMatcher.equals(board.getFQBN())) {
153+
return true;
154+
}
155+
}
156+
157+
// Identification properties are defined in boards.txt with a ".N" suffix
158+
// for example:
159+
//
160+
// uno.name=Arduino/Genuino Uno
161+
// uno.vid.0=0x2341
162+
// uno.pid.0=0x0043
163+
// uno.vid.1=0x2341
164+
// uno.pid.1=0x0001
165+
// uno.vid.2=0x2A03
166+
// uno.pid.2=0x0043
167+
// uno.vid.3=0x2341
168+
// uno.pid.3=0x0243
169+
//
170+
// so we must search starting from suffix ".0" and increasing until we
171+
// found a match or the board has no more identification properties defined
172+
173+
for (int suffix = 0;; suffix++) {
174+
boolean found = true;
175+
for (String prop : identificationProps.keySet()) {
176+
String value = identificationProps.get(prop);
177+
prop += "." + suffix;
178+
if (!boardProps.containsKey(prop)) {
179+
return false;
180+
}
181+
if (!value.equalsIgnoreCase(boardProps.get(prop))) {
182+
found = false;
183+
break;
184+
}
185+
}
186+
if (found) {
187+
return true;
188+
}
189+
}
117190
}
191+
118192
}

0 commit comments

Comments
 (0)