diff --git a/src/main/c/Posix/SerialPort_Posix.c b/src/main/c/Posix/SerialPort_Posix.c index 96e02e9..a903b7a 100644 --- a/src/main/c/Posix/SerialPort_Posix.c +++ b/src/main/c/Posix/SerialPort_Posix.c @@ -2,7 +2,7 @@ * SerialPort_Posix.c * * Created on: Feb 25, 2012 - * Last Updated on: Dec 01, 2021 + * Last Updated on: Dec 07, 2021 * Author: Will Hedgecock * * Copyright (C) 2012-2021 Fazecast, Inc. @@ -33,6 +33,7 @@ #include #include #include +#include #include #if defined(__linux__) #include @@ -52,6 +53,7 @@ jfieldID eventListenerRunningField; jfieldID disableConfigField; jfieldID isDtrEnabledField; jfieldID isRtsEnabledField; +jfieldID autoFlushIOBuffersField; jfieldID baudRateField; jfieldID dataBitsField; jfieldID stopBitsField; @@ -135,6 +137,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z"); isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z"); isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z"); + autoFlushIOBuffersField = (*env)->GetFieldID(env, serialCommClass, "autoFlushIOBuffers", "Z"); baudRateField = (*env)->GetFieldID(env, serialCommClass, "baudRate", "I"); dataBitsField = (*env)->GetFieldID(env, serialCommClass, "dataBits", "I"); stopBitsField = (*env)->GetFieldID(env, serialCommClass, "stopBits", "I"); @@ -185,6 +188,7 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative( const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL); unsigned char disableExclusiveLock = (*env)->GetBooleanField(env, obj, disableExclusiveLockField); unsigned char disableAutoConfig = (*env)->GetBooleanField(env, obj, disableConfigField); + unsigned char autoFlushIOBuffers = (*env)->GetBooleanField(env, obj, autoFlushIOBuffersField); // Ensure that the serial port still exists and is not already open serialPort *port = fetchPort(&serialPorts, portName); @@ -220,6 +224,13 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative( errno = 0; port->handle = -1; } + else if (autoFlushIOBuffers) + { + // Sleep to workaround kernel bug about flushing immediately after opening + const struct timespec sleep_time = { 0, 10000000 }; + nanosleep(&sleep_time, NULL); + Java_com_fazecast_jSerialComm_SerialPort_flushRxTxBuffers(env, obj, (jlong)(intptr_t)port); + } } else port->errorNumber = errno; @@ -427,6 +438,18 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou return JNI_TRUE; } +JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_flushRxTxBuffers(JNIEnv *env, jobject obj, jlong serialPortPointer) +{ + serialPort *port = (serialPort*)(intptr_t)serialPortPointer; + if (tcflush(port->handle, TCIOFLUSH)) + { + port->errorLineNumber = __LINE__ - 2; + port->errorNumber = errno; + return JNI_FALSE; + } + return JNI_TRUE; +} + JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNIEnv *env, jobject obj, jlong serialPortPointer) { // Initialize the local variables diff --git a/src/main/c/Posix/com_fazecast_jSerialComm_SerialPort.h b/src/main/c/Posix/com_fazecast_jSerialComm_SerialPort.h index 218d980..66dfc38 100644 --- a/src/main/c/Posix/com_fazecast_jSerialComm_SerialPort.h +++ b/src/main/c/Posix/com_fazecast_jSerialComm_SerialPort.h @@ -129,6 +129,14 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeouts (JNIEnv *, jobject, jlong, jint, jint, jint, jint); +/* + * Class: com_fazecast_jSerialComm_SerialPort + * Method: flushRxTxBuffers + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_flushRxTxBuffers + (JNIEnv *, jobject, jlong); + /* * Class: com_fazecast_jSerialComm_SerialPort * Method: waitForEvent diff --git a/src/main/c/Windows/SerialPort_Windows.c b/src/main/c/Windows/SerialPort_Windows.c index 378b639..598f606 100644 --- a/src/main/c/Windows/SerialPort_Windows.c +++ b/src/main/c/Windows/SerialPort_Windows.c @@ -2,7 +2,7 @@ * SerialPort_Windows.c * * Created on: Feb 25, 2012 - * Last Updated on: Dec 06, 2021 + * Last Updated on: Dec 07, 2021 * Author: Will Hedgecock * * Copyright (C) 2012-2021 Fazecast, Inc. @@ -49,6 +49,7 @@ jfieldID eventListenerRunningField; jfieldID disableConfigField; jfieldID isDtrEnabledField; jfieldID isRtsEnabledField; +jfieldID autoFlushIOBuffersField; jfieldID baudRateField; jfieldID dataBitsField; jfieldID stopBitsField; @@ -366,6 +367,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z"); isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z"); isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z"); + autoFlushIOBuffersField = (*env)->GetFieldID(env, serialCommClass, "autoFlushIOBuffers", "Z"); baudRateField = (*env)->GetFieldID(env, serialCommClass, "baudRate", "I"); dataBitsField = (*env)->GetFieldID(env, serialCommClass, "dataBits", "I"); stopBitsField = (*env)->GetFieldID(env, serialCommClass, "stopBits", "I"); @@ -396,6 +398,7 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative( jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField); const wchar_t *portName = (wchar_t*)(*env)->GetStringChars(env, portNameJString, NULL); unsigned char disableAutoConfig = (*env)->GetBooleanField(env, obj, disableConfigField); + unsigned char autoFlushIOBuffers = (*env)->GetBooleanField(env, obj, autoFlushIOBuffersField); // Ensure that the serial port still exists and is not already open serialPort *port = fetchPort(&serialPorts, portName); @@ -423,6 +426,8 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative( CloseHandle(port->handle); port->handle = INVALID_HANDLE_VALUE; } + else if (autoFlushIOBuffers) + Java_com_fazecast_jSerialComm_SerialPort_flushRxTxBuffers(env, obj, (jlong)(intptr_t)port); } else { @@ -573,6 +578,18 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou return JNI_TRUE; } +JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_flushRxTxBuffers(JNIEnv *env, jobject obj, jlong serialPortPointer) +{ + serialPort *port = (serialPort*)(intptr_t)serialPortPointer; + if (PurgeComm(port->handle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR) == 0) + { + port->errorLineNumber = __LINE__ - 2; + port->errorNumber = GetLastError(); + return JNI_FALSE; + } + return JNI_TRUE; +} + JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNIEnv *env, jobject obj, jlong serialPortPointer) { // Create an asynchronous event structure diff --git a/src/main/java/com/fazecast/jSerialComm/SerialPort.java b/src/main/java/com/fazecast/jSerialComm/SerialPort.java index a905bdf..89e3f84 100644 --- a/src/main/java/com/fazecast/jSerialComm/SerialPort.java +++ b/src/main/java/com/fazecast/jSerialComm/SerialPort.java @@ -421,7 +421,7 @@ public final class SerialPort private volatile String comPort, friendlyName, portDescription; private volatile boolean eventListenerRunning = false, disableConfig = false, disableExclusiveLock = false; private volatile boolean rs485Mode = false, rs485ActiveHigh = true, rs485RxDuringTx = false, rs485EnableTermination = false; - private volatile boolean isRtsEnabled = true, isDtrEnabled = true; + private volatile boolean isRtsEnabled = true, isDtrEnabled = true, autoFlushIOBuffers = false; private SerialPortInputStream inputStream = null; private SerialPortOutputStream outputStream = null; @@ -592,6 +592,7 @@ public final class SerialPort private final native long closePortNative(long portHandle); // Closes serial port private final native boolean configPort(long portHandle); // Changes/sets serial port parameters as defined by this class private final native boolean configTimeouts(long portHandle, int timeoutMode, int readTimeout, int writeTimeout, int eventsToMonitor); // Changes/sets serial port timeouts as defined by this class + private final native boolean flushRxTxBuffers(long portHandle); // Flushes underlying RX/TX device buffers private final native int waitForEvent(long portHandle); // Waits for serial event to occur as specified in eventFlags private final native int bytesAvailable(long portHandle); // Returns number of bytes available for reading private final native int bytesAwaitingWrite(long portHandle); // Returns number of bytes still waiting to be written @@ -966,6 +967,27 @@ public final class SerialPort return outputStream; } + /** + * Flushes the serial port's Rx/Tx device buffers. + *

+ * If this function is called before the port is open, then the buffers will be flushed immediately after opening the port. + * If called on an already-open port, flushing of the buffers will happen immediately. + *

+ * Note that flushing serial buffers will always work on real serial ports; however, many USB-to-serial converters + * do not accurately implement this functionality, so the flushing may not always work as expected, especially immediately + * after opening a new port. + * + * @return Whether the IO buffers were (or will be) successfully flushed. + */ + public final synchronized boolean flushIOBuffers() + { + autoFlushIOBuffers = true; + + if (portHandle > 0) + return flushRxTxBuffers(portHandle); + return true; + } + /** * Sets all serial port parameters at one time. *

diff --git a/src/main/resources/Android/arm64-v8a/libjSerialComm.so b/src/main/resources/Android/arm64-v8a/libjSerialComm.so index 3b2c06a..63f155f 100644 Binary files a/src/main/resources/Android/arm64-v8a/libjSerialComm.so and b/src/main/resources/Android/arm64-v8a/libjSerialComm.so differ diff --git a/src/main/resources/Android/armeabi-v7a/libjSerialComm.so b/src/main/resources/Android/armeabi-v7a/libjSerialComm.so index 63672a6..dce9acf 100644 Binary files a/src/main/resources/Android/armeabi-v7a/libjSerialComm.so and b/src/main/resources/Android/armeabi-v7a/libjSerialComm.so differ diff --git a/src/main/resources/Android/x86/libjSerialComm.so b/src/main/resources/Android/x86/libjSerialComm.so index bb0e567..5d140f0 100644 Binary files a/src/main/resources/Android/x86/libjSerialComm.so and b/src/main/resources/Android/x86/libjSerialComm.so differ diff --git a/src/main/resources/Android/x86_64/libjSerialComm.so b/src/main/resources/Android/x86_64/libjSerialComm.so index 5b0fae4..3961ef4 100644 Binary files a/src/main/resources/Android/x86_64/libjSerialComm.so and b/src/main/resources/Android/x86_64/libjSerialComm.so differ diff --git a/src/main/resources/FreeBSD/arm64/libjSerialComm.so b/src/main/resources/FreeBSD/arm64/libjSerialComm.so index 48a6fe9..9bf4374 100644 Binary files a/src/main/resources/FreeBSD/arm64/libjSerialComm.so and b/src/main/resources/FreeBSD/arm64/libjSerialComm.so differ diff --git a/src/main/resources/FreeBSD/x86/libjSerialComm.so b/src/main/resources/FreeBSD/x86/libjSerialComm.so index b711e03..20390a9 100644 Binary files a/src/main/resources/FreeBSD/x86/libjSerialComm.so and b/src/main/resources/FreeBSD/x86/libjSerialComm.so differ diff --git a/src/main/resources/FreeBSD/x86_64/libjSerialComm.so b/src/main/resources/FreeBSD/x86_64/libjSerialComm.so index 883af0d..d2464cf 100644 Binary files a/src/main/resources/FreeBSD/x86_64/libjSerialComm.so and b/src/main/resources/FreeBSD/x86_64/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv5/libjSerialComm.so b/src/main/resources/Linux/armv5/libjSerialComm.so index 7e4e9a4..a3c1216 100644 Binary files a/src/main/resources/Linux/armv5/libjSerialComm.so and b/src/main/resources/Linux/armv5/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv6/libjSerialComm.so b/src/main/resources/Linux/armv6/libjSerialComm.so index 8e788ac..9ce4060 100644 Binary files a/src/main/resources/Linux/armv6/libjSerialComm.so and b/src/main/resources/Linux/armv6/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv6hf/libjSerialComm.so b/src/main/resources/Linux/armv6hf/libjSerialComm.so index d62be0b..d19c295 100644 Binary files a/src/main/resources/Linux/armv6hf/libjSerialComm.so and b/src/main/resources/Linux/armv6hf/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv7/libjSerialComm.so b/src/main/resources/Linux/armv7/libjSerialComm.so index 622c007..369e11d 100644 Binary files a/src/main/resources/Linux/armv7/libjSerialComm.so and b/src/main/resources/Linux/armv7/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv7hf/libjSerialComm.so b/src/main/resources/Linux/armv7hf/libjSerialComm.so index e1493d0..9e131ce 100644 Binary files a/src/main/resources/Linux/armv7hf/libjSerialComm.so and b/src/main/resources/Linux/armv7hf/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv8_32/libjSerialComm.so b/src/main/resources/Linux/armv8_32/libjSerialComm.so index 53c3a5f..40937d6 100644 Binary files a/src/main/resources/Linux/armv8_32/libjSerialComm.so and b/src/main/resources/Linux/armv8_32/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv8_64/libjSerialComm.so b/src/main/resources/Linux/armv8_64/libjSerialComm.so index 4e6f45d..32faea1 100644 Binary files a/src/main/resources/Linux/armv8_64/libjSerialComm.so and b/src/main/resources/Linux/armv8_64/libjSerialComm.so differ diff --git a/src/main/resources/Linux/ppc64le/libjSerialComm.so b/src/main/resources/Linux/ppc64le/libjSerialComm.so index 76dd432..d4b8dac 100644 Binary files a/src/main/resources/Linux/ppc64le/libjSerialComm.so and b/src/main/resources/Linux/ppc64le/libjSerialComm.so differ diff --git a/src/main/resources/Linux/x86/libjSerialComm.so b/src/main/resources/Linux/x86/libjSerialComm.so index 6a730b4..6c17659 100644 Binary files a/src/main/resources/Linux/x86/libjSerialComm.so and b/src/main/resources/Linux/x86/libjSerialComm.so differ diff --git a/src/main/resources/Linux/x86_64/libjSerialComm.so b/src/main/resources/Linux/x86_64/libjSerialComm.so index f541396..31a9c41 100644 Binary files a/src/main/resources/Linux/x86_64/libjSerialComm.so and b/src/main/resources/Linux/x86_64/libjSerialComm.so differ diff --git a/src/main/resources/OSX/aarch64/libjSerialComm.jnilib b/src/main/resources/OSX/aarch64/libjSerialComm.jnilib index 4dd0c6a..2656413 100755 Binary files a/src/main/resources/OSX/aarch64/libjSerialComm.jnilib and b/src/main/resources/OSX/aarch64/libjSerialComm.jnilib differ diff --git a/src/main/resources/OSX/x86/libjSerialComm.jnilib b/src/main/resources/OSX/x86/libjSerialComm.jnilib index c38d8ef..c990187 100644 Binary files a/src/main/resources/OSX/x86/libjSerialComm.jnilib and b/src/main/resources/OSX/x86/libjSerialComm.jnilib differ diff --git a/src/main/resources/OSX/x86_64/libjSerialComm.jnilib b/src/main/resources/OSX/x86_64/libjSerialComm.jnilib index 64db6e2..4643fb4 100755 Binary files a/src/main/resources/OSX/x86_64/libjSerialComm.jnilib and b/src/main/resources/OSX/x86_64/libjSerialComm.jnilib differ diff --git a/src/main/resources/Solaris/sparcv8plus_32/libjSerialComm.so b/src/main/resources/Solaris/sparcv8plus_32/libjSerialComm.so index 444b6f6..b7985ef 100644 Binary files a/src/main/resources/Solaris/sparcv8plus_32/libjSerialComm.so and b/src/main/resources/Solaris/sparcv8plus_32/libjSerialComm.so differ diff --git a/src/main/resources/Solaris/sparcv9_64/libjSerialComm.so b/src/main/resources/Solaris/sparcv9_64/libjSerialComm.so index dcb965a..d8dc9a7 100644 Binary files a/src/main/resources/Solaris/sparcv9_64/libjSerialComm.so and b/src/main/resources/Solaris/sparcv9_64/libjSerialComm.so differ diff --git a/src/main/resources/Solaris/x86/libjSerialComm.so b/src/main/resources/Solaris/x86/libjSerialComm.so index c0097b2..905cb50 100644 Binary files a/src/main/resources/Solaris/x86/libjSerialComm.so and b/src/main/resources/Solaris/x86/libjSerialComm.so differ diff --git a/src/main/resources/Solaris/x86_64/libjSerialComm.so b/src/main/resources/Solaris/x86_64/libjSerialComm.so index c7824f5..d2fc3d2 100644 Binary files a/src/main/resources/Solaris/x86_64/libjSerialComm.so and b/src/main/resources/Solaris/x86_64/libjSerialComm.so differ diff --git a/src/main/resources/Windows/aarch64/jSerialComm.dll b/src/main/resources/Windows/aarch64/jSerialComm.dll index a631a62..495f909 100644 Binary files a/src/main/resources/Windows/aarch64/jSerialComm.dll and b/src/main/resources/Windows/aarch64/jSerialComm.dll differ diff --git a/src/main/resources/Windows/armv7/jSerialComm.dll b/src/main/resources/Windows/armv7/jSerialComm.dll index 783e108..0bbdda6 100644 Binary files a/src/main/resources/Windows/armv7/jSerialComm.dll and b/src/main/resources/Windows/armv7/jSerialComm.dll differ diff --git a/src/main/resources/Windows/x86/jSerialComm.dll b/src/main/resources/Windows/x86/jSerialComm.dll index 2b3b9ae..ea446b6 100644 Binary files a/src/main/resources/Windows/x86/jSerialComm.dll and b/src/main/resources/Windows/x86/jSerialComm.dll differ diff --git a/src/main/resources/Windows/x86_64/jSerialComm.dll b/src/main/resources/Windows/x86_64/jSerialComm.dll index d42126e..780f7c6 100644 Binary files a/src/main/resources/Windows/x86_64/jSerialComm.dll and b/src/main/resources/Windows/x86_64/jSerialComm.dll differ