1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-01-18 07:52:14 +01:00

Merge pull request #4211 from facchinm/iserial_field

cross-platform jni implementation for serial port details discovery
This commit is contained in:
Martino Facchin 2016-01-07 12:25:10 +00:00
commit a1c79ce188
12 changed files with 69 additions and 114 deletions

View File

@ -47,7 +47,7 @@ public class SerialBoardsLister extends TimerTask {
}
public void start(Timer timer) {
timer.schedule(this, 0, 3000);
timer.schedule(this, 0, 1000);
}
@Override
@ -75,7 +75,7 @@ public class SerialBoardsLister extends TimerTask {
}
for (String port : ports) {
Map<String, Object> boardData = platform.resolveDeviceAttachedTo(port, BaseNoGui.packages, devicesListOutput);
Map<String, Object> boardData = platform.resolveDeviceByVendorIdProductId(port, BaseNoGui.packages, devicesListOutput);
BoardPort boardPort = new BoardPort();
boardPort.setAddress(port);
@ -86,6 +86,7 @@ public class SerialBoardsLister extends TimerTask {
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());
TargetBoard board = (TargetBoard) boardData.get("board");
if (board != null) {

View File

@ -110,6 +110,8 @@ public class SSHUploader extends Uploader {
SSHClientSetupChainRing sshClientSetupChain = new SSHConfigFileSetup(new SSHPwdSetup());
session = sshClientSetupChain.setup(port, jSch);
session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
session.setUserInfo(new NoInteractionUserInfo(PreferencesData.get("runtime.pwd." + port.getAddress())));
session.connect(30000);

View File

@ -37,6 +37,7 @@ package cc.arduino.packages.uploaders;
import cc.arduino.LoadVIDPIDSpecificPreferences;
import cc.arduino.packages.Uploader;
import processing.app.*;
import cc.arduino.packages.BoardPort;
import processing.app.debug.RunnerException;
import processing.app.debug.TargetPlatform;
import processing.app.helpers.OSUtils;
@ -152,6 +153,13 @@ public class SerialUploader extends Uploader {
}
}
BoardPort boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port"));
try {
prefs.put("serial.port.iserial", boardPort.getPrefs().get("iserial"));
} catch (Exception e) {
// if serial port does not contain an iserial field
}
prefs.put("build.path", buildPath);
prefs.put("build.project_name", className);
if (verbose) {

View File

@ -144,15 +144,30 @@ public class Platform {
}
}
public Map<String, Object> resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
return null;
static {
loadLib(new File(BaseNoGui.getContentFile("lib"), System.mapLibraryName("listSerialsj")));
};
private static void loadLib(File lib) {
try {
System.load(lib.getAbsolutePath());
} catch (UnsatisfiedLinkError e) {
e.printStackTrace();
System.out.println(e.getMessage());
System.out.println("Cannot load native library " + lib.getAbsolutePath());
System.out.println("The program has terminated!");
System.exit(1);
}
}
public native String resolveDeviceAttachedToNative(String serial);
public String preListAllCandidateDevices() {
return null;
}
protected Map<String, Object> resolveDeviceByVendorIdProductId(Map<String, TargetPackage> packages, String readVIDPID) {
public Map<String, Object> resolveDeviceByVendorIdProductId(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
String vid_pid_iSerial = resolveDeviceAttachedToNative(serial);
for (TargetPackage targetPackage : packages.values()) {
for (TargetPlatform targetPlatform : targetPackage.getPlatforms().values()) {
for (TargetBoard board : targetPlatform.getBoards().values()) {
@ -161,11 +176,12 @@ public class Platform {
List<String> pids = new LinkedList<String>(board.getPreferences().subTree("pid", 1).values());
for (int i = 0; i < vids.size(); i++) {
String vidPid = vids.get(i) + "_" + pids.get(i);
if (vidPid.toUpperCase().equals(readVIDPID)) {
if (vid_pid_iSerial.toUpperCase().contains(vidPid.toUpperCase())) {
Map<String, Object> boardData = new HashMap<String, Object>();
boardData.put("board", board);
boardData.put("vid", vids.get(i));
boardData.put("pid", pids.get(i));
boardData.put("iserial", vid_pid_iSerial.substring(vidPid.length()+1));
return boardData;
}
}

View File

@ -120,30 +120,4 @@ public class Platform extends processing.app.Platform {
public String getName() {
return PConstants.platformNames[PConstants.LINUX];
}
@Override
public Map<String, Object> resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
assert packages != null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Executor executor = new DefaultExecutor();
executor.setStreamHandler(new PumpStreamHandler(baos, null));
try {
CommandLine toDevicePath = CommandLine.parse("udevadm info -q path -n " + serial);
executor.execute(toDevicePath);
String devicePath = new String(baos.toByteArray());
baos.reset();
CommandLine commandLine = CommandLine.parse("udevadm info --query=property -p " + devicePath);
executor.execute(commandLine);
String vidPid = new UDevAdmParser().extractVIDAndPID(new String(baos.toByteArray()));
if (vidPid == null) {
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
}
return super.resolveDeviceByVendorIdProductId(packages, vidPid);
} catch (IOException e) {
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
}
}
}

View File

@ -12,9 +12,13 @@ public class UDevAdmParser {
Object vid = properties.get("ID_VENDOR_ID");
Object pid = properties.get("ID_MODEL_ID");
Object serial = properties.get("ID_SERIAL_SHORT");
if (vid == null || pid == null)
return null;
return ("0x" + vid + "_0x" + pid).toUpperCase();
if (serial == null) {
serial = "";
}
return ("0x" + vid + "_0x" + pid).toUpperCase() + "_" + serial;
}
}

View File

@ -164,41 +164,6 @@ public class Platform extends processing.app.Platform {
return PConstants.platformNames[PConstants.MACOSX];
}
@Override
public Map<String, Object> resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
assert packages != null;
if (devicesListOutput == null) {
return super.resolveDeviceAttachedTo(serial, packages, null);
}
try {
String vidPid = new SystemProfilerParser().extractVIDAndPID(devicesListOutput, serial);
if (vidPid == null) {
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
}
return super.resolveDeviceByVendorIdProductId(packages, vidPid);
} catch (IOException e) {
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
}
}
@Override
public String preListAllCandidateDevices() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Executor executor = new DefaultExecutor();
executor.setStreamHandler(new PumpStreamHandler(baos, null));
try {
CommandLine toDevicePath = CommandLine.parse("/usr/sbin/system_profiler SPUSBDataType");
executor.execute(toDevicePath);
return new String(baos.toByteArray());
} catch (Throwable e) {
return super.preListAllCandidateDevices();
}
}
@Override
public java.util.List<BoardPort> filterPorts(java.util.List<BoardPort> ports, boolean showAll) {
if (showAll) {

View File

@ -81,7 +81,7 @@ public class SystemProfilerParser {
String computedDevicePathMinusChar = computedDevicePath.substring(0, computedDevicePath.length() - 1);
String serialMinusChar = serial.substring(0, serial.length() - 1);
if (computedDevicePath.equalsIgnoreCase(serial) || computedDevicePathMinusChar.equalsIgnoreCase(serialMinusChar)) {
return (device.get(VID) + "_" + device.get(PID)).toUpperCase();
return (device.get(VID) + "_" + device.get(PID)).toUpperCase() + "_" + device.get(SERIAL_NUMBER);
}
}
device = new HashMap<>();

View File

@ -59,8 +59,9 @@ public class ListComPortsParser {
String vidPidPart = lineParts[lineParts.length - 1];
Matcher vidMatcher = vidRegExp.matcher(vidPidPart);
Matcher pidMatcher = pidRegExp.matcher(vidPidPart);
String iSerial = vidPidPart.substring(vidPidPart.lastIndexOf("\\")+1);
if (vidMatcher.find() && pidMatcher.find()) {
return ("0x" + vidMatcher.group(1) + "_0x" + pidMatcher.group(1)).toUpperCase();
return ("0x" + vidMatcher.group(1) + "_0x" + pidMatcher.group(1)).toUpperCase() + "_" + iSerial;
}
}
}

View File

@ -183,43 +183,6 @@ public class Platform extends processing.app.Platform {
return PConstants.platformNames[PConstants.WINDOWS];
}
@Override
public Map<String, Object> resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
assert packages != null;
if (devicesListOutput == null) {
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
}
try {
String vidPid = new ListComPortsParser().extractVIDAndPID(devicesListOutput, serial);
if (vidPid == null) {
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
}
return super.resolveDeviceByVendorIdProductId(packages, vidPid);
} catch (IOException e) {
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
}
}
@Override
public String preListAllCandidateDevices() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Executor executor = new DefaultExecutor();
executor.setStreamHandler(new PumpStreamHandler(baos, null));
try {
String listComPorts = BaseNoGui.getContentFile("hardware/tools/listComPorts.exe").getCanonicalPath();
CommandLine toDevicePath = CommandLine.parse(listComPorts);
executor.execute(toDevicePath);
return new String(baos.toByteArray());
} catch (Throwable e) {
return super.preListAllCandidateDevices();
}
}
@Override
public void fixPrefsFilePermissions(File prefsFile) throws IOException {
//noop

View File

@ -393,6 +393,15 @@
<copy file="macosx/libastylej-2.05.1/libastylej.jnilib" tofile="macosx/work/${staging_hardware_folder}/../lib/libastylej.dylib" />
<chmod perm="755" file="macosx/work/${staging_hardware_folder}/../lib/libastylej.dylib" />
<antcall target="unzip">
<param name="archive_file" value="./liblistSerials-1.0.4.zip" />
<param name="archive_url" value="http://downloads.arduino.cc/liblistSerials/liblistSerials-1.0.4.zip" />
<param name="final_folder" value="${staging_folder}/liblistSerials-1.0.4" />
<param name="dest_folder" value="${staging_folder}" />
</antcall>
<copy file="macosx/liblistSerials-1.0.4/osx/liblistSerialsj.dylib" todir="macosx/work/${staging_hardware_folder}/../lib/" />
<chmod perm="755" file="macosx/work/${staging_hardware_folder}/../lib/liblistSerialsj.dylib" />
<delete dir="${staging_folder}/arduino-builder-macosx" includeemptydirs="true"/>
<mkdir dir="${staging_folder}/arduino-builder-macosx"/>
<antcall target="untar">
@ -585,6 +594,16 @@
<antcall target="portable-${portable}">
<param name="parentdir" value="linux/work" />
</antcall>
<antcall target="unzip">
<param name="archive_file" value="./liblistSerials-1.0.4.zip" />
<param name="archive_url" value="http://downloads.arduino.cc/liblistSerials/liblistSerials-1.0.4.zip" />
<param name="final_folder" value="${staging_folder}/liblistSerials-1.0.4" />
<param name="dest_folder" value="${staging_folder}" />
</antcall>
<copy file="linux/liblistSerials-1.0.4/linux${arch-bits}/liblistSerialsj.so" todir="linux/work/lib/" />
<chmod perm="755" file="linux/work/lib/liblistSerialsj.so" />
</target>
<target name="linux32-build" depends="linux-build" description="Build linux (32-bit) version">
@ -845,13 +864,14 @@
<copy file="windows/msvcp100.dll" todir="windows/work" />
<copy file="windows/msvcr100.dll" todir="windows/work" />
<!-- Copy listComPort.exe tool -->
<copy todir="windows/work/hardware/tools">
<fileset file="windows/listComPorts.exe" />
</copy>
<chmod perm="755">
<fileset file="windows/work/hardware/tools/listComPorts.exe" />
</chmod>
<antcall target="unzip">
<param name="archive_file" value="./liblistSerials-1.0.4.zip" />
<param name="archive_url" value="http://downloads.arduino.cc/liblistSerials/liblistSerials-1.0.4.zip" />
<param name="final_folder" value="${staging_folder}/liblistSerials-1.0.4" />
<param name="dest_folder" value="${staging_folder}" />
</antcall>
<copy file="windows/liblistSerials-1.0.4/windows/listSerialsj.dll" todir="windows/work/lib/" />
<chmod perm="755" file="windows/work/lib/listSerialsj.dll" />
<delete dir="${staging_folder}/arduino-builder-windows" includeemptydirs="true"/>
<mkdir dir="${staging_folder}/arduino-builder-windows"/>

View File

@ -0,0 +1 @@
4e8ef727d7dc3903c37002f38f8aba87796b787c