mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-17 06:52:18 +01:00
working on #223: Auto-detection of serial ports. Mac version ready even if a bit slow
This commit is contained in:
parent
776952762f
commit
0d47f22787
@ -134,18 +134,18 @@ public class Platform {
|
||||
}
|
||||
}
|
||||
|
||||
public String resolveDeviceAttachedTo(String device, Map<String, TargetPackage> packages) {
|
||||
public String resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String resolveDeviceByVendorIdProductId(Map<String, TargetPackage> packages, String vendorId, String productId) {
|
||||
protected String resolveDeviceByVendorIdProductId(Map<String, TargetPackage> packages, String readVIDPID) {
|
||||
for (TargetPackage targetPackage : packages.values()) {
|
||||
for (TargetPlatform targetPlatform : targetPackage.getPlatforms().values()) {
|
||||
for (PreferencesMap board : targetPlatform.getBoards().values()) {
|
||||
if (board.containsKey("vid_pid")) {
|
||||
String[] vidPids = board.get("vid_pid").split(",");
|
||||
for (String vidPid : vidPids) {
|
||||
if (vidPid.toUpperCase().equals(vendorId + "_" + productId)) {
|
||||
if (vidPid.toUpperCase().equals(readVIDPID)) {
|
||||
return board.get("name");
|
||||
}
|
||||
}
|
||||
|
@ -22,12 +22,6 @@
|
||||
|
||||
package processing.app.linux;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import org.apache.commons.exec.CommandLine;
|
||||
import org.apache.commons.exec.DefaultExecutor;
|
||||
import org.apache.commons.exec.ExecuteStreamHandler;
|
||||
@ -36,6 +30,9 @@ import processing.app.Preferences;
|
||||
import processing.app.debug.TargetPackage;
|
||||
import processing.core.PConstants;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Used by Base for platform-specific tweaking, for instance finding the
|
||||
@ -171,11 +168,15 @@ public class Platform extends processing.app.Platform {
|
||||
baos.reset();
|
||||
CommandLine commandLine = CommandLine.parse("udevadm info --query=property -p " + devicePath);
|
||||
executor.execute(commandLine);
|
||||
Properties properties = new Properties();
|
||||
properties.load(new ByteArrayInputStream(baos.toByteArray()));
|
||||
return super.resolveDeviceByVendorIdProductId(packages, properties.get("ID_VENDOR_ID").toString().toUpperCase(), properties.get("ID_MODEL_ID").toString().toUpperCase());
|
||||
String vidPid = new UDevAdmParser().extractVIDAndPID(new String(baos.toByteArray()));
|
||||
|
||||
if (vidPid == null) {
|
||||
return super.resolveDeviceAttachedTo(serial, packages);
|
||||
}
|
||||
|
||||
return super.resolveDeviceByVendorIdProductId(packages, vidPid);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
return super.resolveDeviceAttachedTo(serial, packages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
16
app/src/processing/app/linux/UDevAdmParser.java
Normal file
16
app/src/processing/app/linux/UDevAdmParser.java
Normal file
@ -0,0 +1,16 @@
|
||||
package processing.app.linux;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Properties;
|
||||
|
||||
public class UDevAdmParser {
|
||||
|
||||
public String extractVIDAndPID(String output) throws IOException {
|
||||
Properties properties = new Properties();
|
||||
properties.load(new StringReader(output));
|
||||
|
||||
return properties.get("ID_VENDOR_ID").toString().toUpperCase() + "_" + properties.get("ID_MODEL_ID").toString().toUpperCase();
|
||||
}
|
||||
|
||||
}
|
@ -22,20 +22,23 @@
|
||||
|
||||
package processing.app.macosx;
|
||||
|
||||
import java.awt.Insets;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import com.apple.eio.FileManager;
|
||||
|
||||
import org.apache.commons.exec.CommandLine;
|
||||
import org.apache.commons.exec.DefaultExecutor;
|
||||
import org.apache.commons.exec.ExecuteStreamHandler;
|
||||
import org.apache.commons.exec.Executor;
|
||||
import processing.app.Base;
|
||||
import processing.app.debug.TargetPackage;
|
||||
import processing.core.PApplet;
|
||||
import processing.core.PConstants;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Platform handler for Mac OS X.
|
||||
@ -202,4 +205,52 @@ public class Platform extends processing.app.Platform {
|
||||
return PConstants.platformNames[PConstants.MACOSX];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages) {
|
||||
Executor executor = new DefaultExecutor();
|
||||
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
executor.setStreamHandler(new ExecuteStreamHandler() {
|
||||
@Override
|
||||
public void setProcessInputStream(OutputStream outputStream) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProcessErrorStream(InputStream inputStream) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProcessOutputStream(InputStream inputStream) throws IOException {
|
||||
byte[] buf = new byte[4096];
|
||||
int bytes = -1;
|
||||
while ((bytes = inputStream.read(buf)) != -1) {
|
||||
baos.write(buf, 0, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
CommandLine toDevicePath = CommandLine.parse("/usr/sbin/system_profiler SPUSBDataType");
|
||||
executor.execute(toDevicePath);
|
||||
String output = new String(baos.toByteArray());
|
||||
|
||||
String vidPid = new SystemProfilerParser().extractVIDAndPID(output, serial);
|
||||
|
||||
if (vidPid == null) {
|
||||
return super.resolveDeviceAttachedTo(serial, packages);
|
||||
}
|
||||
|
||||
return super.resolveDeviceByVendorIdProductId(packages, vidPid);
|
||||
} catch (IOException e) {
|
||||
return super.resolveDeviceAttachedTo(serial, packages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
62
app/src/processing/app/macosx/SystemProfilerParser.java
Normal file
62
app/src/processing/app/macosx/SystemProfilerParser.java
Normal file
@ -0,0 +1,62 @@
|
||||
package processing.app.macosx;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SystemProfilerParser {
|
||||
|
||||
private final Pattern vidRegex;
|
||||
private final Pattern serialNumberRegex;
|
||||
private final Pattern locationRegex;
|
||||
private final Pattern pidRegex;
|
||||
|
||||
public SystemProfilerParser() {
|
||||
serialNumberRegex = Pattern.compile("^Serial Number: (.+)$");
|
||||
locationRegex = Pattern.compile("^Location ID: (.+)$");
|
||||
pidRegex = Pattern.compile("^Product ID: (.+)$");
|
||||
vidRegex = Pattern.compile("^Vendor ID: (.+)$");
|
||||
}
|
||||
|
||||
public String extractVIDAndPID(String output, String serial) throws IOException {
|
||||
BufferedReader reader = new BufferedReader(new StringReader(output));
|
||||
|
||||
String devicePrefix;
|
||||
if (serial.startsWith("/dev/tty.")) {
|
||||
devicePrefix = "/dev/tty.usbmodem";
|
||||
} else {
|
||||
devicePrefix = "/dev/cu.usbmodem";
|
||||
}
|
||||
|
||||
Map<String, String> device = new HashMap<String, String>();
|
||||
|
||||
String line;
|
||||
Matcher matcher;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
line = line.trim();
|
||||
line = line.replaceAll("\\s+", " ");
|
||||
|
||||
if ((matcher = serialNumberRegex.matcher(line)).matches()) {
|
||||
device.put("serial_number", matcher.group(1));
|
||||
} else if ((matcher = locationRegex.matcher(line)).matches()) {
|
||||
device.put("device_path", devicePrefix + matcher.group(1).substring(2, 6) + "1");
|
||||
} else if ((matcher = pidRegex.matcher(line)).matches()) {
|
||||
device.put("pid", matcher.group(1));
|
||||
} else if ((matcher = vidRegex.matcher(line)).matches()) {
|
||||
device.put("vid", matcher.group(1));
|
||||
} else if (line.equals("")) {
|
||||
if (device.containsKey("serial_number") && device.get("device_path").equals(serial)) {
|
||||
return device.get("vid").substring(2).toUpperCase() + "_" + device.get("pid").substring(2).toUpperCase();
|
||||
}
|
||||
device = new HashMap<String, String>();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
21
app/test/processing/app/TestHelper.java
Normal file
21
app/test/processing/app/TestHelper.java
Normal file
@ -0,0 +1,21 @@
|
||||
package processing.app;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class TestHelper {
|
||||
|
||||
public static String inputStreamToString(InputStream is) throws IOException {
|
||||
StringWriter sw = new StringWriter();
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||
String line;
|
||||
try {
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sw.append(line).append('\n');
|
||||
}
|
||||
return sw.toString();
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
}
|
16
app/test/processing/app/linux/UDevAdmParserTest.java
Normal file
16
app/test/processing/app/linux/UDevAdmParserTest.java
Normal file
@ -0,0 +1,16 @@
|
||||
package processing.app.linux;
|
||||
|
||||
import org.junit.Test;
|
||||
import processing.app.TestHelper;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class UDevAdmParserTest {
|
||||
|
||||
@Test
|
||||
public void shouldCorrectlyParse() throws Exception {
|
||||
String output = TestHelper.inputStreamToString(UDevAdmParserTest.class.getResourceAsStream("udev_output.txt"));
|
||||
|
||||
assertEquals("2341_0036", new UDevAdmParser().extractVIDAndPID(output));
|
||||
}
|
||||
}
|
24
app/test/processing/app/linux/udev_output.txt
Normal file
24
app/test/processing/app/linux/udev_output.txt
Normal file
@ -0,0 +1,24 @@
|
||||
DEVLINKS=/dev/arduino_leonardo /dev/serial/by-id/usb-Arduino_LLC_Arduino_Leonardo-if00 /dev/serial/by-path/pci-0000:00:14.0-usb-0:2.3:1.0
|
||||
DEVNAME=/dev/ttyACM0
|
||||
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2.3/3-2.3:1.0/tty/ttyACM0
|
||||
ID_BUS=usb
|
||||
ID_MM_CANDIDATE=1
|
||||
ID_MODEL=Arduino_Leonardo
|
||||
ID_MODEL_ENC=Arduino\x20Leonardo
|
||||
ID_MODEL_ID=0036
|
||||
ID_PATH=pci-0000:00:14.0-usb-0:2.3:1.0
|
||||
ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_3_1_0
|
||||
ID_REVISION=0001
|
||||
ID_SERIAL=Arduino_LLC_Arduino_Leonardo
|
||||
ID_TYPE=generic
|
||||
ID_USB_DRIVER=cdc_acm
|
||||
ID_USB_INTERFACES=:020201:0a0000:
|
||||
ID_USB_INTERFACE_NUM=00
|
||||
ID_VENDOR=Arduino_LLC
|
||||
ID_VENDOR_ENC=Arduino\x20LLC
|
||||
ID_VENDOR_ID=2341
|
||||
MAJOR=166
|
||||
MINOR=0
|
||||
SUBSYSTEM=tty
|
||||
UDEV_LOG=3
|
||||
USEC_INITIALIZED=21035594802
|
17
app/test/processing/app/macosx/SystemProfilerParserTest.java
Normal file
17
app/test/processing/app/macosx/SystemProfilerParserTest.java
Normal file
@ -0,0 +1,17 @@
|
||||
package processing.app.macosx;
|
||||
|
||||
import org.junit.Test;
|
||||
import processing.app.TestHelper;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class SystemProfilerParserTest {
|
||||
|
||||
@Test
|
||||
public void shouldCorrectlyParse() throws Exception {
|
||||
String output = TestHelper.inputStreamToString(SystemProfilerParserTest.class.getResourceAsStream("system_profiler_output.txt"));
|
||||
|
||||
assertEquals("2341_0044", new SystemProfilerParser().extractVIDAndPID(output, "/dev/cu.usbmodemfa121"));
|
||||
assertEquals("2341_0044", new SystemProfilerParser().extractVIDAndPID(output, "/dev/tty.usbmodemfa121"));
|
||||
}
|
||||
}
|
134
app/test/processing/app/macosx/system_profiler_output.txt
Normal file
134
app/test/processing/app/macosx/system_profiler_output.txt
Normal file
@ -0,0 +1,134 @@
|
||||
USB:
|
||||
|
||||
USB High-Speed Bus:
|
||||
|
||||
Host Controller Location: Built-in USB
|
||||
Host Controller Driver: AppleUSBEHCI
|
||||
PCI Device ID: 0x1c2d
|
||||
PCI Revision ID: 0x0005
|
||||
PCI Vendor ID: 0x8086
|
||||
Bus Number: 0xfa
|
||||
|
||||
Hub:
|
||||
|
||||
Product ID: 0x2513
|
||||
Vendor ID: 0x0424 (SMSC)
|
||||
Version: b.b3
|
||||
Speed: Up to 480 Mb/sec
|
||||
Location ID: 0xfa100000 / 2
|
||||
Current Available (mA): 500
|
||||
Current Required (mA): 2
|
||||
|
||||
Trans-It Drive:
|
||||
|
||||
Capacity: 3.99 GB (3,992,977,408 bytes)
|
||||
Removable Media: Yes
|
||||
Detachable Drive: Yes
|
||||
BSD Name: disk1
|
||||
Product ID: 0x0622
|
||||
Vendor ID: 0x0718 (Imation Corp.)
|
||||
Version: 1.10
|
||||
Serial Number: 0792181A2BDD
|
||||
Speed: Up to 480 Mb/sec
|
||||
Manufacturer: TDKMedia
|
||||
Location ID: 0xfa130000 / 6
|
||||
Current Available (mA): 500
|
||||
Current Required (mA): 300
|
||||
Partition Map Type: MBR (Master Boot Record)
|
||||
S.M.A.R.T. status: Not Supported
|
||||
Volumes:
|
||||
Untitled:
|
||||
Capacity: 3.99 GB (3,990,379,520 bytes)
|
||||
Available: 1.99 GB (1,986,838,528 bytes)
|
||||
Writable: Yes
|
||||
File System: MS-DOS FAT32
|
||||
BSD Name: disk1s1
|
||||
Mount Point: /Volumes/Untitled
|
||||
Content: Windows_FAT_32
|
||||
|
||||
Arduino Mega ADK:
|
||||
|
||||
Product ID: 0x0044
|
||||
Vendor ID: 0x2341
|
||||
Version: 0.01
|
||||
Serial Number: 64936333936351500000
|
||||
Speed: Up to 12 Mb/sec
|
||||
Manufacturer: Arduino (www.arduino.cc)
|
||||
Location ID: 0xfa120000 / 5
|
||||
Current Available (mA): 500
|
||||
Current Required (mA): 100
|
||||
|
||||
BRCM20702 Hub:
|
||||
|
||||
Product ID: 0x4500
|
||||
Vendor ID: 0x0a5c (Broadcom Corp.)
|
||||
Version: 1.00
|
||||
Speed: Up to 12 Mb/sec
|
||||
Manufacturer: Apple Inc.
|
||||
Location ID: 0xfa110000 / 3
|
||||
Current Available (mA): 500
|
||||
Current Required (mA): 94
|
||||
|
||||
Bluetooth USB Host Controller:
|
||||
|
||||
Product ID: 0x8281
|
||||
Vendor ID: 0x05ac (Apple Inc.)
|
||||
Version: 0.97
|
||||
Speed: Up to 12 Mb/sec
|
||||
Manufacturer: Apple Inc.
|
||||
Location ID: 0xfa113000 / 4
|
||||
Current Available (mA): 500
|
||||
Current Required (mA): 0
|
||||
|
||||
USB High-Speed Bus:
|
||||
|
||||
Host Controller Location: Built-in USB
|
||||
Host Controller Driver: AppleUSBEHCI
|
||||
PCI Device ID: 0x7ffc00001c26
|
||||
PCI Revision ID: 0x7ffc00000005
|
||||
PCI Vendor ID: 0x7ffc00008086
|
||||
Bus Number: 0xfd
|
||||
|
||||
Hub:
|
||||
|
||||
Product ID: 0x2513
|
||||
Vendor ID: 0x0424 (SMSC)
|
||||
Version: b.b3
|
||||
Speed: Up to 480 Mb/sec
|
||||
Location ID: 0xfd100000 / 2
|
||||
Current Available (mA): 500
|
||||
Current Required (mA): 2
|
||||
|
||||
USB Multimedia Keyboard:
|
||||
|
||||
Product ID: 0xc311
|
||||
Vendor ID: 0x046d (Logitech Inc.)
|
||||
Version: 1.30
|
||||
Speed: Up to 1.5 Mb/sec
|
||||
Manufacturer: BTC
|
||||
Location ID: 0xfd120000 / 5
|
||||
Current Available (mA): 500
|
||||
Current Required (mA): 100
|
||||
|
||||
USB-PS/2 Optical Mouse:
|
||||
|
||||
Product ID: 0xc050
|
||||
Vendor ID: 0x046d (Logitech Inc.)
|
||||
Version: 27.20
|
||||
Speed: Up to 1.5 Mb/sec
|
||||
Manufacturer: Logitech
|
||||
Location ID: 0xfd130000 / 4
|
||||
Current Available (mA): 500
|
||||
Current Required (mA): 98
|
||||
|
||||
IR Receiver:
|
||||
|
||||
Product ID: 0x8242
|
||||
Vendor ID: 0x05ac (Apple Inc.)
|
||||
Version: 0.16
|
||||
Speed: Up to 1.5 Mb/sec
|
||||
Manufacturer: Apple Computer, Inc.
|
||||
Location ID: 0xfd110000 / 3
|
||||
Current Available (mA): 500
|
||||
Current Required (mA): 100
|
||||
|
@ -76,7 +76,7 @@
|
||||
<!-- In 0149, removed /System/Library/Java from the CLASSPATH because
|
||||
it can cause problems if users have installed weird files there.
|
||||
http://dev.processing.org/bugs/show_bug.cgi?id=1045 -->
|
||||
<string>$JAVAROOT/pde.jar:$JAVAROOT/core.jar:$JAVAROOT/antlr.jar:$JAVAROOT/ecj.jar:$JAVAROOT/registry.jar:$JAVAROOT/quaqua.jar:$JAVAROOT/RXTXcomm.jar</string>
|
||||
<string>$JAVAROOT/pde.jar:$JAVAROOT/core.jar:$JAVAROOT/antlr.jar:$JAVAROOT/ecj.jar:$JAVAROOT/registry.jar:$JAVAROOT/quaqua.jar:$JAVAROOT/RXTXcomm.jar:$JAVAROOT/commons-exec-1.1.jar</string>
|
||||
|
||||
<key>JVMArchs</key>
|
||||
<array>
|
||||
|
Loading…
x
Reference in New Issue
Block a user