Skip to content

Commit a1c79ce

Browse files
committed
Merge pull request #4211 from facchinm/iserial_field
cross-platform jni implementation for serial port details discovery
2 parents 4100ead + 2a677b4 commit a1c79ce

File tree

12 files changed

+69
-114
lines changed

12 files changed

+69
-114
lines changed

arduino-core/src/cc/arduino/packages/discoverers/serial/SerialBoardsLister.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public SerialBoardsLister(SerialDiscovery serialDiscovery) {
4747
}
4848

4949
public void start(Timer timer) {
50-
timer.schedule(this, 0, 3000);
50+
timer.schedule(this, 0, 1000);
5151
}
5252

5353
@Override
@@ -75,7 +75,7 @@ public void run() {
7575
}
7676

7777
for (String port : ports) {
78-
Map<String, Object> boardData = platform.resolveDeviceAttachedTo(port, BaseNoGui.packages, devicesListOutput);
78+
Map<String, Object> boardData = platform.resolveDeviceByVendorIdProductId(port, BaseNoGui.packages, devicesListOutput);
7979

8080
BoardPort boardPort = new BoardPort();
8181
boardPort.setAddress(port);
@@ -86,6 +86,7 @@ public void run() {
8686
if (boardData != null) {
8787
boardPort.getPrefs().put("vid", boardData.get("vid").toString());
8888
boardPort.getPrefs().put("pid", boardData.get("pid").toString());
89+
boardPort.getPrefs().put("iserial", boardData.get("iserial").toString());
8990

9091
TargetBoard board = (TargetBoard) boardData.get("board");
9192
if (board != null) {

arduino-core/src/cc/arduino/packages/uploaders/SSHUploader.java

+2
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String
110110
SSHClientSetupChainRing sshClientSetupChain = new SSHConfigFileSetup(new SSHPwdSetup());
111111
session = sshClientSetupChain.setup(port, jSch);
112112

113+
session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
114+
113115
session.setUserInfo(new NoInteractionUserInfo(PreferencesData.get("runtime.pwd." + port.getAddress())));
114116
session.connect(30000);
115117

arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java

+8
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import cc.arduino.LoadVIDPIDSpecificPreferences;
3838
import cc.arduino.packages.Uploader;
3939
import processing.app.*;
40+
import cc.arduino.packages.BoardPort;
4041
import processing.app.debug.RunnerException;
4142
import processing.app.debug.TargetPlatform;
4243
import processing.app.helpers.OSUtils;
@@ -152,6 +153,13 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String
152153
}
153154
}
154155

156+
BoardPort boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port"));
157+
try {
158+
prefs.put("serial.port.iserial", boardPort.getPrefs().get("iserial"));
159+
} catch (Exception e) {
160+
// if serial port does not contain an iserial field
161+
}
162+
155163
prefs.put("build.path", buildPath);
156164
prefs.put("build.project_name", className);
157165
if (verbose) {

arduino-core/src/processing/app/Platform.java

+20-4
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,30 @@ public void openFolder(File file) throws Exception {
144144
}
145145
}
146146

147-
public Map<String, Object> resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
148-
return null;
147+
static {
148+
loadLib(new File(BaseNoGui.getContentFile("lib"), System.mapLibraryName("listSerialsj")));
149+
};
150+
151+
private static void loadLib(File lib) {
152+
try {
153+
System.load(lib.getAbsolutePath());
154+
} catch (UnsatisfiedLinkError e) {
155+
e.printStackTrace();
156+
System.out.println(e.getMessage());
157+
System.out.println("Cannot load native library " + lib.getAbsolutePath());
158+
System.out.println("The program has terminated!");
159+
System.exit(1);
160+
}
149161
}
150162

163+
public native String resolveDeviceAttachedToNative(String serial);
164+
151165
public String preListAllCandidateDevices() {
152166
return null;
153167
}
154168

155-
protected Map<String, Object> resolveDeviceByVendorIdProductId(Map<String, TargetPackage> packages, String readVIDPID) {
169+
public Map<String, Object> resolveDeviceByVendorIdProductId(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
170+
String vid_pid_iSerial = resolveDeviceAttachedToNative(serial);
156171
for (TargetPackage targetPackage : packages.values()) {
157172
for (TargetPlatform targetPlatform : targetPackage.getPlatforms().values()) {
158173
for (TargetBoard board : targetPlatform.getBoards().values()) {
@@ -161,11 +176,12 @@ protected Map<String, Object> resolveDeviceByVendorIdProductId(Map<String, Targe
161176
List<String> pids = new LinkedList<String>(board.getPreferences().subTree("pid", 1).values());
162177
for (int i = 0; i < vids.size(); i++) {
163178
String vidPid = vids.get(i) + "_" + pids.get(i);
164-
if (vidPid.toUpperCase().equals(readVIDPID)) {
179+
if (vid_pid_iSerial.toUpperCase().contains(vidPid.toUpperCase())) {
165180
Map<String, Object> boardData = new HashMap<String, Object>();
166181
boardData.put("board", board);
167182
boardData.put("vid", vids.get(i));
168183
boardData.put("pid", pids.get(i));
184+
boardData.put("iserial", vid_pid_iSerial.substring(vidPid.length()+1));
169185
return boardData;
170186
}
171187
}

arduino-core/src/processing/app/linux/Platform.java

-26
Original file line numberDiff line numberDiff line change
@@ -120,30 +120,4 @@ public void openFolder(File file) throws Exception {
120120
public String getName() {
121121
return PConstants.platformNames[PConstants.LINUX];
122122
}
123-
124-
@Override
125-
public Map<String, Object> resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
126-
assert packages != null;
127-
ByteArrayOutputStream baos = new ByteArrayOutputStream();
128-
Executor executor = new DefaultExecutor();
129-
executor.setStreamHandler(new PumpStreamHandler(baos, null));
130-
131-
try {
132-
CommandLine toDevicePath = CommandLine.parse("udevadm info -q path -n " + serial);
133-
executor.execute(toDevicePath);
134-
String devicePath = new String(baos.toByteArray());
135-
baos.reset();
136-
CommandLine commandLine = CommandLine.parse("udevadm info --query=property -p " + devicePath);
137-
executor.execute(commandLine);
138-
String vidPid = new UDevAdmParser().extractVIDAndPID(new String(baos.toByteArray()));
139-
140-
if (vidPid == null) {
141-
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
142-
}
143-
144-
return super.resolveDeviceByVendorIdProductId(packages, vidPid);
145-
} catch (IOException e) {
146-
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
147-
}
148-
}
149123
}

arduino-core/src/processing/app/linux/UDevAdmParser.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ public String extractVIDAndPID(String output) throws IOException {
1212

1313
Object vid = properties.get("ID_VENDOR_ID");
1414
Object pid = properties.get("ID_MODEL_ID");
15+
Object serial = properties.get("ID_SERIAL_SHORT");
1516
if (vid == null || pid == null)
1617
return null;
17-
return ("0x" + vid + "_0x" + pid).toUpperCase();
18+
if (serial == null) {
19+
serial = "";
20+
}
21+
return ("0x" + vid + "_0x" + pid).toUpperCase() + "_" + serial;
1822
}
1923

2024
}

arduino-core/src/processing/app/macosx/Platform.java

-35
Original file line numberDiff line numberDiff line change
@@ -164,41 +164,6 @@ public String getName() {
164164
return PConstants.platformNames[PConstants.MACOSX];
165165
}
166166

167-
@Override
168-
public Map<String, Object> resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
169-
assert packages != null;
170-
if (devicesListOutput == null) {
171-
return super.resolveDeviceAttachedTo(serial, packages, null);
172-
}
173-
174-
try {
175-
String vidPid = new SystemProfilerParser().extractVIDAndPID(devicesListOutput, serial);
176-
177-
if (vidPid == null) {
178-
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
179-
}
180-
181-
return super.resolveDeviceByVendorIdProductId(packages, vidPid);
182-
} catch (IOException e) {
183-
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
184-
}
185-
}
186-
187-
@Override
188-
public String preListAllCandidateDevices() {
189-
ByteArrayOutputStream baos = new ByteArrayOutputStream();
190-
Executor executor = new DefaultExecutor();
191-
executor.setStreamHandler(new PumpStreamHandler(baos, null));
192-
193-
try {
194-
CommandLine toDevicePath = CommandLine.parse("/usr/sbin/system_profiler SPUSBDataType");
195-
executor.execute(toDevicePath);
196-
return new String(baos.toByteArray());
197-
} catch (Throwable e) {
198-
return super.preListAllCandidateDevices();
199-
}
200-
}
201-
202167
@Override
203168
public java.util.List<BoardPort> filterPorts(java.util.List<BoardPort> ports, boolean showAll) {
204169
if (showAll) {

arduino-core/src/processing/app/macosx/SystemProfilerParser.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public String extractVIDAndPID(String output, String serial) throws IOException
8181
String computedDevicePathMinusChar = computedDevicePath.substring(0, computedDevicePath.length() - 1);
8282
String serialMinusChar = serial.substring(0, serial.length() - 1);
8383
if (computedDevicePath.equalsIgnoreCase(serial) || computedDevicePathMinusChar.equalsIgnoreCase(serialMinusChar)) {
84-
return (device.get(VID) + "_" + device.get(PID)).toUpperCase();
84+
return (device.get(VID) + "_" + device.get(PID)).toUpperCase() + "_" + device.get(SERIAL_NUMBER);
8585
}
8686
}
8787
device = new HashMap<>();

arduino-core/src/processing/app/windows/ListComPortsParser.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@ public String extractVIDAndPID(String output, String serial) throws IOException
5959
String vidPidPart = lineParts[lineParts.length - 1];
6060
Matcher vidMatcher = vidRegExp.matcher(vidPidPart);
6161
Matcher pidMatcher = pidRegExp.matcher(vidPidPart);
62+
String iSerial = vidPidPart.substring(vidPidPart.lastIndexOf("\\")+1);
6263
if (vidMatcher.find() && pidMatcher.find()) {
63-
return ("0x" + vidMatcher.group(1) + "_0x" + pidMatcher.group(1)).toUpperCase();
64+
return ("0x" + vidMatcher.group(1) + "_0x" + pidMatcher.group(1)).toUpperCase() + "_" + iSerial;
6465
}
6566
}
6667
}

arduino-core/src/processing/app/windows/Platform.java

-37
Original file line numberDiff line numberDiff line change
@@ -183,43 +183,6 @@ public String getName() {
183183
return PConstants.platformNames[PConstants.WINDOWS];
184184
}
185185

186-
@Override
187-
public Map<String, Object> resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
188-
assert packages != null;
189-
if (devicesListOutput == null) {
190-
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
191-
}
192-
193-
try {
194-
String vidPid = new ListComPortsParser().extractVIDAndPID(devicesListOutput, serial);
195-
196-
if (vidPid == null) {
197-
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
198-
}
199-
200-
return super.resolveDeviceByVendorIdProductId(packages, vidPid);
201-
} catch (IOException e) {
202-
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
203-
}
204-
}
205-
206-
@Override
207-
public String preListAllCandidateDevices() {
208-
ByteArrayOutputStream baos = new ByteArrayOutputStream();
209-
Executor executor = new DefaultExecutor();
210-
executor.setStreamHandler(new PumpStreamHandler(baos, null));
211-
212-
try {
213-
String listComPorts = BaseNoGui.getContentFile("hardware/tools/listComPorts.exe").getCanonicalPath();
214-
215-
CommandLine toDevicePath = CommandLine.parse(listComPorts);
216-
executor.execute(toDevicePath);
217-
return new String(baos.toByteArray());
218-
} catch (Throwable e) {
219-
return super.preListAllCandidateDevices();
220-
}
221-
}
222-
223186
@Override
224187
public void fixPrefsFilePermissions(File prefsFile) throws IOException {
225188
//noop

build/build.xml

+27-7
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,15 @@
393393
<copy file="macosx/libastylej-2.05.1/libastylej.jnilib" tofile="macosx/work/${staging_hardware_folder}/../lib/libastylej.dylib" />
394394
<chmod perm="755" file="macosx/work/${staging_hardware_folder}/../lib/libastylej.dylib" />
395395

396+
<antcall target="unzip">
397+
<param name="archive_file" value="./liblistSerials-1.0.4.zip" />
398+
<param name="archive_url" value="http://downloads.arduino.cc/liblistSerials/liblistSerials-1.0.4.zip" />
399+
<param name="final_folder" value="${staging_folder}/liblistSerials-1.0.4" />
400+
<param name="dest_folder" value="${staging_folder}" />
401+
</antcall>
402+
<copy file="macosx/liblistSerials-1.0.4/osx/liblistSerialsj.dylib" todir="macosx/work/${staging_hardware_folder}/../lib/" />
403+
<chmod perm="755" file="macosx/work/${staging_hardware_folder}/../lib/liblistSerialsj.dylib" />
404+
396405
<delete dir="${staging_folder}/arduino-builder-macosx" includeemptydirs="true"/>
397406
<mkdir dir="${staging_folder}/arduino-builder-macosx"/>
398407
<antcall target="untar">
@@ -585,6 +594,16 @@
585594
<antcall target="portable-${portable}">
586595
<param name="parentdir" value="linux/work" />
587596
</antcall>
597+
598+
<antcall target="unzip">
599+
<param name="archive_file" value="./liblistSerials-1.0.4.zip" />
600+
<param name="archive_url" value="http://downloads.arduino.cc/liblistSerials/liblistSerials-1.0.4.zip" />
601+
<param name="final_folder" value="${staging_folder}/liblistSerials-1.0.4" />
602+
<param name="dest_folder" value="${staging_folder}" />
603+
</antcall>
604+
<copy file="linux/liblistSerials-1.0.4/linux${arch-bits}/liblistSerialsj.so" todir="linux/work/lib/" />
605+
<chmod perm="755" file="linux/work/lib/liblistSerialsj.so" />
606+
588607
</target>
589608

590609
<target name="linux32-build" depends="linux-build" description="Build linux (32-bit) version">
@@ -845,13 +864,14 @@
845864
<copy file="windows/msvcp100.dll" todir="windows/work" />
846865
<copy file="windows/msvcr100.dll" todir="windows/work" />
847866

848-
<!-- Copy listComPort.exe tool -->
849-
<copy todir="windows/work/hardware/tools">
850-
<fileset file="windows/listComPorts.exe" />
851-
</copy>
852-
<chmod perm="755">
853-
<fileset file="windows/work/hardware/tools/listComPorts.exe" />
854-
</chmod>
867+
<antcall target="unzip">
868+
<param name="archive_file" value="./liblistSerials-1.0.4.zip" />
869+
<param name="archive_url" value="http://downloads.arduino.cc/liblistSerials/liblistSerials-1.0.4.zip" />
870+
<param name="final_folder" value="${staging_folder}/liblistSerials-1.0.4" />
871+
<param name="dest_folder" value="${staging_folder}" />
872+
</antcall>
873+
<copy file="windows/liblistSerials-1.0.4/windows/listSerialsj.dll" todir="windows/work/lib/" />
874+
<chmod perm="755" file="windows/work/lib/listSerialsj.dll" />
855875

856876
<delete dir="${staging_folder}/arduino-builder-windows" includeemptydirs="true"/>
857877
<mkdir dir="${staging_folder}/arduino-builder-windows"/>

build/liblistSerials-1.0.4.zip.sha

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
4e8ef727d7dc3903c37002f38f8aba87796b787c

0 commit comments

Comments
 (0)