Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
authorJonah Graham2020-05-11 16:40:03 +0000
committerJonah Graham2020-05-15 18:32:47 +0000
commitda0d1d7df6e5db543ef808c2cc99e037fecb7805 (patch)
treed6b28528b8970a005d4cbe0d793c5a3f388e15d9 /native
parentfc7e62940fad723d4caa72df6331bb5fe27612a8 (diff)
downloadorg.eclipse.cdt-da0d1d7df6e5db543ef808c2cc99e037fecb7805.tar.gz
org.eclipse.cdt-da0d1d7df6e5db543ef808c2cc99e037fecb7805.tar.xz
org.eclipse.cdt-da0d1d7df6e5db543ef808c2cc99e037fecb7805.zip
Bug 543122: Add additional baud rates for serial
Includes new API to allow, on platforms that support it, setting and getting arbitrary rates. Change-Id: I0b1134325f913bb09d1bf0cd902f89e968d80570
Diffstat (limited to 'native')
-rw-r--r--native/org.eclipse.cdt.native.serial/META-INF/MANIFEST.MF2
-rw-r--r--native/org.eclipse.cdt.native.serial/jni/serial.c111
-rwxr-xr-xnative/org.eclipse.cdt.native.serial/os/linux/x86_64/libserial.sobin13192 -> 13224 bytes
-rwxr-xr-xnative/org.eclipse.cdt.native.serial/os/macosx/x86_64/libserial.jnilibbin13756 -> 13756 bytes
-rwxr-xr-xnative/org.eclipse.cdt.native.serial/os/win32/x86_64/serial.dllbin380597 -> 381152 bytes
-rw-r--r--native/org.eclipse.cdt.native.serial/pom.xml4
-rw-r--r--native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/BaudRate.java135
-rw-r--r--native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/SerialPort.java37
-rw-r--r--native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/StandardBaudRates.java59
9 files changed, 305 insertions, 43 deletions
diff --git a/native/org.eclipse.cdt.native.serial/META-INF/MANIFEST.MF b/native/org.eclipse.cdt.native.serial/META-INF/MANIFEST.MF
index 79326a762a7..79a8bc63545 100644
--- a/native/org.eclipse.cdt.native.serial/META-INF/MANIFEST.MF
+++ b/native/org.eclipse.cdt.native.serial/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Serial Port
Bundle-SymbolicName: org.eclipse.cdt.native.serial
-Bundle-Version: 1.1.500.qualifier
+Bundle-Version: 1.2.0.qualifier
Bundle-Vendor: Eclipse CDT
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: org.eclipse.cdt.serial
diff --git a/native/org.eclipse.cdt.native.serial/jni/serial.c b/native/org.eclipse.cdt.native.serial/jni/serial.c
index 95d3b57f379..bd77e74bffc 100644
--- a/native/org.eclipse.cdt.native.serial/jni/serial.c
+++ b/native/org.eclipse.cdt.native.serial/jni/serial.c
@@ -27,6 +27,9 @@
#include <strings.h>
#include <errno.h>
#include <sys/ioctl.h>
+#ifndef __APPLE__
+#include <linux/serial.h>
+#endif
#else
#define WIN32_LEAN_AND_MEAN
#define UNICODE
@@ -36,6 +39,29 @@
#define FUNC(x) Java_org_eclipse_cdt_serial_SerialPort_ ## x
+/**
+ * Use this method to throw an exception when open fails after the OS open
+ * stage. This method obtains the last error from OS to include in the
+ * IOException
+ */
+#ifndef __MINGW32__
+static void closeAndthrowIOException(int fd, JNIEnv *env, const char *msg)
+#else
+static void closeAndthrowIOException(HANDLE handle, JNIEnv *env, const char *msg)
+#endif
+{
+ char buff[256];
+#ifndef __MINGW32__
+ sprintf(buff, "%s: %s", msg, strerror(errno));
+ close(fd);
+#else
+ sprintf_s(buff, sizeof(buff), "%s (%d)", msg, GetLastError());
+ CloseHandle(handle);
+#endif
+ jclass cls = (*env)->FindClass(env, "java/io/IOException");
+ (*env)->ThrowNew(env, cls, buff);
+}
+
static void throwIOException(JNIEnv *env, const char *msg)
{
char buff[256];
@@ -69,6 +95,7 @@ JNIEXPORT jlong JNICALL FUNC(open0)(JNIEnv *env, jobject jobj, jstring portName,
tcgetattr(fd, &options);
options.c_cflag |= (CLOCAL | CREAD);
+#ifndef __APPLE__
speed_t baud;
switch (baudRate) {
case 110:
@@ -104,12 +131,82 @@ JNIEXPORT jlong JNICALL FUNC(open0)(JNIEnv *env, jobject jobj, jstring portName,
case 115200:
baud = B115200;
break;
+ case 230400:
+ baud = B230400;
+ break;
+ case 460800:
+ baud = B460800;
+ break;
+ case 500000:
+ baud = B500000;
+ break;
+ case 576000:
+ baud = B576000;
+ break;
+ case 921600:
+ baud = B921600;
+ break;
+ case 1000000:
+ baud = B1000000;
+ break;
+ case 1152000:
+ baud = B1152000;
+ break;
+ case 1500000:
+ baud = B1500000;
+ break;
+ case 2000000:
+ baud = B2000000;
+ break;
+ case 2500000:
+ baud = B2500000;
+ break;
+ case 3000000:
+ baud = B3000000;
+ break;
+ case 3500000:
+ baud = B3500000;
+ break;
+ case 4000000:
+ baud = B4000000;
+ break;
default:
- baud = B115200;
+ baud = B0;
+ break;
}
- // Set baud rate
- cfsetispeed(&options, baud);
- cfsetospeed(&options, baud);
+
+ if (baud == B0) {
+ // Use custom linux baud rates if possible: https://bugs.eclipse.org/bugs/show_bug.cgi?id=543122#c8
+ struct serial_struct serial_options;
+ options.c_cflag |= B38400;
+
+ if (ioctl(fd, TIOCGSERIAL, &serial_options) != 0) {
+ closeAndthrowIOException(fd, env, "Failed to use custom baud rate. Error using TIOCGSERIAL");
+ return -1;
+ }
+ serial_options.custom_divisor = serial_options.baud_base / baudRate;
+ if (serial_options.custom_divisor == 0) {
+ serial_options.custom_divisor = 1;
+ }
+
+ serial_options.flags &= ~ASYNC_SPD_MASK;
+ serial_options.flags |= ASYNC_SPD_CUST;
+
+ if (ioctl(fd, TIOCSSERIAL, &serial_options) != 0) {
+ closeAndthrowIOException(fd, env, "Failed to use custom baud rate. Error using TIOCSSERIAL");
+ return -1;
+ }
+ } else {
+ // Set baud rate
+ cfsetispeed(&options, baud);
+ cfsetospeed(&options, baud);
+ }
+
+#else
+ // On OSX speed_t is simply the baud rate: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/cfsetispeed.3.html
+ cfsetispeed(&options, baudRate);
+ cfsetospeed(&options, baudRate);
+#endif
// set data size
options.c_cflag &= ~CSIZE;
@@ -191,7 +288,7 @@ JNIEXPORT jlong JNICALL FUNC(open0)(JNIEnv *env, jobject jobj, jstring portName,
DCB dcb = { 0 };
if (!GetCommState(handle, &dcb)) {
- throwIOException(env, "Error getting DCB");
+ closeAndthrowIOException(handle, env, "Error getting DCB");
return -1;
}
@@ -223,7 +320,7 @@ JNIEXPORT jlong JNICALL FUNC(open0)(JNIEnv *env, jobject jobj, jstring portName,
}
if (!SetCommState(handle, &dcb)) {
- throwIOException(env, "Error setting DCB");
+ closeAndthrowIOException(handle, env, "Error setting DCB");
return -1;
}
@@ -232,7 +329,7 @@ JNIEXPORT jlong JNICALL FUNC(open0)(JNIEnv *env, jobject jobj, jstring portName,
timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 200;
if (!SetCommTimeouts(handle, &timeouts)) {
- throwIOException(env, "Error setting timeouts");
+ closeAndthrowIOException(handle, env, "Error setting timeouts");
return -1;
}
diff --git a/native/org.eclipse.cdt.native.serial/os/linux/x86_64/libserial.so b/native/org.eclipse.cdt.native.serial/os/linux/x86_64/libserial.so
index e672cbefdac..535d0a795c0 100755
--- a/native/org.eclipse.cdt.native.serial/os/linux/x86_64/libserial.so
+++ b/native/org.eclipse.cdt.native.serial/os/linux/x86_64/libserial.so
Binary files differ
diff --git a/native/org.eclipse.cdt.native.serial/os/macosx/x86_64/libserial.jnilib b/native/org.eclipse.cdt.native.serial/os/macosx/x86_64/libserial.jnilib
index aaa319e00c7..ff4cbab0bdd 100755
--- a/native/org.eclipse.cdt.native.serial/os/macosx/x86_64/libserial.jnilib
+++ b/native/org.eclipse.cdt.native.serial/os/macosx/x86_64/libserial.jnilib
Binary files differ
diff --git a/native/org.eclipse.cdt.native.serial/os/win32/x86_64/serial.dll b/native/org.eclipse.cdt.native.serial/os/win32/x86_64/serial.dll
index 856f1399c32..2b1a6fab520 100755
--- a/native/org.eclipse.cdt.native.serial/os/win32/x86_64/serial.dll
+++ b/native/org.eclipse.cdt.native.serial/os/win32/x86_64/serial.dll
Binary files differ
diff --git a/native/org.eclipse.cdt.native.serial/pom.xml b/native/org.eclipse.cdt.native.serial/pom.xml
index 5a9e0cde877..38302debf3d 100644
--- a/native/org.eclipse.cdt.native.serial/pom.xml
+++ b/native/org.eclipse.cdt.native.serial/pom.xml
@@ -5,7 +5,7 @@
are made available under the terms of the Eclipse Public License 2.0
which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-2.0/
-
+
SPDX-License-Identifier: EPL-2.0
Contributors:
@@ -23,7 +23,7 @@
<relativePath>../../pom.xml</relativePath>
</parent>
- <version>1.1.500-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<artifactId>org.eclipse.cdt.native.serial</artifactId>
<packaging>eclipse-plugin</packaging>
diff --git a/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/BaudRate.java b/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/BaudRate.java
index ada49ce4485..8a20d3329b9 100644
--- a/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/BaudRate.java
+++ b/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/BaudRate.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015 QNX Software Systems and others.
+ * Copyright (c) 2015, 2020 QNX Software Systems and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -13,60 +13,135 @@
*******************************************************************************/
package org.eclipse.cdt.serial;
+import java.util.Arrays;
+import java.util.Optional;
+
/**
+ * Standard BaudRates that are generally supported by serial driver.
* @since 1.0
+ * @deprecated Baud Rates are not a fixed set. Instead use {@link StandardBaudRates} for
+ * typical values and use an int to represent baud rates. This deprecation goes
+ * along with {@link SerialPort#setBaudRate(BaudRate)'s deprecation. Use
+ * SerialPort#setBaudRateValue(int) instead.
*/
+@Deprecated
public enum BaudRate {
- B110(110), B300(300), B600(600), B1200(1200), B2400(2400), B4800(4800), B9600(9600), B14400(14400), B19200(19200),
- B38400(38400), B57600(57600), B115200(115200);
+ B110, //
+ B300, //
+ B600, //
+ B1200, //
+ B2400, //
+ B4800, //
+ B9600,
+ /**
+ * 14,400 is not standard on Linux and requires custom baud rate support.
+ */
+ B14400, //
+ B19200, //
+ B38400, //
+ B57600, //
+ B115200,
+ /**
+ * @since 1.2
+ */
+ B230400,
+ /**
+ * @since 1.2
+ */
+ B460800,
+ /**
+ * @since 1.2
+ */
+ B500000,
+ /**
+ * @since 1.2
+ */
+ B576000,
+ /**
+ * @since 1.2
+ */
+ B921600,
+ /**
+ * @since 1.2
+ */
+ B1000000,
+ /**
+ * @since 1.2
+ */
+ B1152000,
+ /**
+ * @since 1.2
+ */
+ B1500000,
+ /**
+ * @since 1.2
+ */
+ B2000000,
+ /**
+ * @since 1.2
+ */
+ B2500000,
+ /**
+ * @since 1.2
+ */
+ B3000000,
+ /**
+ * @since 1.2
+ */
+ B3500000,
+ /**
+ * @since 1.2
+ */
+ B4000000;
private final int rate;
- private BaudRate(int rate) {
- this.rate = rate;
+ BaudRate() {
+ this.rate = Integer.parseInt(toString().substring(1));
}
public int getRate() {
return rate;
}
- private static final String[] strings = { "110", //$NON-NLS-1$
- "300", //$NON-NLS-1$
- "600", //$NON-NLS-1$
- "1200", //$NON-NLS-1$
- "2400", //$NON-NLS-1$
- "4800", //$NON-NLS-1$
- "9600", //$NON-NLS-1$
- "14400", //$NON-NLS-1$
- "19200", //$NON-NLS-1$
- "38400", //$NON-NLS-1$
- "57600", //$NON-NLS-1$
- "115200" //$NON-NLS-1$
- };
+ private String getSpeedString() {
+ return toString().substring(1);
+ }
public static String[] getStrings() {
- return strings;
+ return Arrays.asList(values()).stream().map(BaudRate::getSpeedString).toArray(String[]::new);
}
- private static final BaudRate[] rates = { B110, B300, B600, B1200, B2400, B4800, B9600, B14400, B19200, B38400,
- B57600, B115200 };
-
public static BaudRate fromStringIndex(int rate) {
- return rates[rate];
+ if (rate < values().length && rate >= 0) {
+ return values()[rate];
+ }
+ return getDefault();
}
public static int getStringIndex(BaudRate rate) {
- for (int i = 0; i < rates.length; ++i) {
- if (rate.equals(rates[i])) {
- return i;
- }
- }
- return getStringIndex(getDefault());
+ return rate.ordinal();
+ }
+
+ /**
+ * This method allows some amount of translation between new API that uses ints
+ * for baud rate and those that use BaudRate. It attempts to get the closest
+ * value.
+ *
+ * @since 1.2
+ */
+ public static BaudRate getClosest(int baudRate) {
+ Optional<BaudRate> reduce = Arrays.asList(BaudRate.values()).stream().reduce((result, current) -> {
+ if (Math.abs(baudRate - current.getRate()) < Math.abs(baudRate - result.getRate()))
+ return current;
+ else
+ return result;
+ });
+ return reduce.get();
}
public static BaudRate getDefault() {
return B115200;
}
-
}
diff --git a/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/SerialPort.java b/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/SerialPort.java
index 672895179cc..ef18b1291d0 100644
--- a/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/SerialPort.java
+++ b/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/SerialPort.java
@@ -38,7 +38,7 @@ public class SerialPort {
private boolean isOpen;
private boolean isPaused;
private Object pauseMutex = new Object();
- private BaudRate baudRate = BaudRate.B115200;
+ private int baudRate = StandardBaudRates.getDefault();
private ByteSize byteSize = ByteSize.B8;
private Parity parity = Parity.None;
private StopBits stopBits = StopBits.S1;
@@ -325,7 +325,7 @@ public class SerialPort {
}
public synchronized void open() throws IOException {
- handle = open0(portName, baudRate.getRate(), byteSize.getSize(), parity.ordinal(), stopBits.ordinal());
+ handle = open0(portName, baudRate, byteSize.getSize(), parity.ordinal(), stopBits.ordinal());
isOpen = true;
synchronized (openPorts) {
@@ -393,20 +393,51 @@ public class SerialPort {
return;
}
isPaused = false;
- handle = open0(portName, baudRate.getRate(), byteSize.getSize(), parity.ordinal(), stopBits.ordinal());
+ handle = open0(portName, baudRate, byteSize.getSize(), parity.ordinal(), stopBits.ordinal());
isOpen = true;
pauseMutex.notifyAll();
}
}
+ /**
+ *
+ * @param rate
+ * @throws IOException
+ * @deprecated Use {@link #setBaudRateValue(int)}
+ */
+ @Deprecated
public void setBaudRate(BaudRate rate) throws IOException {
if (isOpen) {
throw new IOException(PORT_OPEN);
}
+ this.baudRate = rate.getRate();
+ }
+
+ /**
+ * @since 1.2
+ */
+ public void setBaudRateValue(int rate) throws IOException {
+ if (isOpen) {
+ throw new IOException(PORT_OPEN);
+ }
this.baudRate = rate;
}
+ /**
+ * @return the baud rate or closest match. Will only
+ * return same value as {@link #setBaudRate(BaudRate)},
+ * may not match value passed {@link #setBaudRateValue(int)}
+ * @deprecated Use {@link #getBaudRateValue()}
+ */
+ @Deprecated
public BaudRate getBaudRate() {
+ return BaudRate.getClosest(baudRate);
+ }
+
+ /**
+ * @since 1.2
+ */
+ public int getBaudRateValue() {
return baudRate;
}
diff --git a/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/StandardBaudRates.java b/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/StandardBaudRates.java
new file mode 100644
index 00000000000..eb9198377c6
--- /dev/null
+++ b/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/StandardBaudRates.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Kichwa Coders Canada Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+= *******************************************************************************/
+package org.eclipse.cdt.serial;
+
+/**
+ * Define the set of baud rates that are standard are generally supported.
+ *
+ * @since 1.2
+ */
+public final class StandardBaudRates {
+ /**
+ * Return an array of the standard values for baud rates.
+ *
+ * Note: Especially on Linux these values are special as they can be set
+ * without requiring operations on the serial port that are not universally
+ * supported.
+ *
+ * The contents of this array may be changed from time to time and therefore
+ * the order of the elements and length of this array should not be used
+ * for anything. In particular, if storing a baud rate preference, store the
+ * integer value of that preference, not the index in this table.
+ *
+ * @return array of standard values
+ */
+ public static int[] asArray() {
+ // This list comes from what linux supports without custom rates.
+ return new int[] { 110, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000,
+ 576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000, 3000000, 3500000, 4000000 };
+ }
+
+ /**
+ * Return an array of the standard values for baud rates, as strings for
+ * display in the UI.
+ * @see #asArray()
+ */
+ public static String[] asStringArray() {
+ int[] rates = asArray();
+ String[] rateStrings = new String[rates.length];
+ for (int i = 0; i < rateStrings.length; i++) {
+ rateStrings[i] = Integer.toString(rates[i]);
+ }
+ return rateStrings;
+ }
+
+ /**
+ * Return the default speed used by the {@link SerialPort}
+ */
+ public static int getDefault() {
+ return 115200;
+ }
+}

Back to the top