Forced flush before close, monitors return value of close(), and releases exclusive lock of port before close.

This commit is contained in:
hedgecrw85 2015-10-09 11:42:15 -05:00
parent ec0acd7ac4
commit 7821161dcc
27 changed files with 171 additions and 86 deletions

14
INSTALL
View File

@ -123,29 +123,29 @@ Maven:
<dependency>
<groupId>com.fazecast</groupId>
<artifactId>jSerialComm</artifactId>
<version>1.3.8</version>
<version>1.3.9</version>
</dependency>
Ivy:
<dependency org="com.fazecast" name="jSerialComm" rev="1.3.8"/>
<dependency org="com.fazecast" name="jSerialComm" rev="1.3.9"/>
Groovy:
@Grab(group='com.fazecast', module='jSerialComm', version='1.3.8')
@Grab(group='com.fazecast', module='jSerialComm', version='1.3.9')
Gradle:
compile 'com.fazecast:jSerialComm:1.3.8'
compile 'com.fazecast:jSerialComm:1.3.9'
Buildr:
compile.with 'com.fazecast:jSerialComm:jar:1.3.8'
compile.with 'com.fazecast:jSerialComm:jar:1.3.9'
Scala/SBT:
libraryDependencies += "com.fazecast" % "jSerialComm" % "1.3.8"
libraryDependencies += "com.fazecast" % "jSerialComm" % "1.3.9"
Leiningen:
[com.fazecast/jSerialComm "1.3.8"]
[com.fazecast/jSerialComm "1.3.9"]

View File

@ -4,7 +4,7 @@ apply plugin: 'maven'
group = 'com.fazecast'
archivesBaseName = 'jSerialComm'
version = '1.3.8'
version = '1.3.9'
sourceCompatibility = 1.6
targetCompatibility = 1.6

View File

@ -4,9 +4,10 @@ include $(CLEAR_VARS)
LOCAL_MODULE := jSerialComm
LOCAL_SRC_FILES := SerialPort_Android.c AndroidHelperFunctions.c
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
all:
cp -rf libs/* ../../resources/Android
rm -rf libs obj/* obj
rm -rf libs/* libs obj

View File

@ -32,6 +32,8 @@
#include <fcntl.h>
#include <asm/termios.h>
#include <asm/ioctls.h>
#include <linux/usbdevice_fs.h>
#include <asm/byteorder.h>
#ifndef BOTHER
#include <termios.h>
#endif
@ -245,18 +247,23 @@ void setBaudRate(int portFD, int baudRate)
{
#ifdef BOTHER
struct termios2 options = { 0 };
ioctl(portFD, TCGETS2, &options);
if (isatty(portFD))
ioctl(portFD, TCGETS2, &options);
options.c_cflag &= ~CBAUD;
options.c_cflag |= BOTHER;
options.c_ispeed = baudRate;
options.c_ospeed = baudRate;
ioctl(portFD, TCSETS2, &options);
if (isatty(portFD))
ioctl(portFD, TCSETS2, &options);
#else
struct termios options = { 0 };
tcgetattr(portFD, &options);
if (isatty(portFD))
ioctl(portFD, TCGETS, &options);
cfsetispeed(&options, B38400);
cfsetospeed(&options, B38400);
tcsetattr(portFD, TCSANOW, &options);
if (isatty(portFD))
ioctl(portFD, TCSETS, &options);
#endif
}

View File

@ -2,7 +2,7 @@
* SerialPort_Android.c
*
* Created on: Mar 13, 2015
* Last Updated on: May 19, 2015
* Last Updated on: Oct 09, 2015
* Author: Will Hedgecock
*
* Copyright (C) 2012-2015 Fazecast, Inc.
@ -27,7 +27,9 @@
#ifndef CMSPAR
#define CMSPAR 010000000000
#endif
#include <android/log.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <dirent.h>
@ -35,9 +37,15 @@
#include <unistd.h>
#include <termios.h>
#include <sys/time.h>
#include <linux/usbdevice_fs.h>
#include <asm/byteorder.h>
#include "com_fazecast_jSerialComm_SerialPort.h"
#include "AndroidHelperFunctions.h"
// Logging defines
#define LOG_TAG "com.fazecast.jSerialComm"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
// Cached class, method, and field IDs
jclass serialCommClass;
jmethodID serialCommConstructor;
@ -104,7 +112,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_uninitializeLibrary(JNIEnv *env, jclass serialComm)
{
// Delete the cache global reference
// Delete the cached global reference
(*env)->DeleteGlobalRef(env, serialCommClass);
}
@ -124,7 +132,7 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
else
{
// Close the port if there was a problem setting the parameters
close(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
}
@ -150,10 +158,12 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
tcflag_t parity = (parityInt == com_fazecast_jSerialComm_SerialPort_NO_PARITY) ? 0 : (parityInt == com_fazecast_jSerialComm_SerialPort_ODD_PARITY) ? (PARENB | PARODD) : (parityInt == com_fazecast_jSerialComm_SerialPort_EVEN_PARITY) ? PARENB : (parityInt == com_fazecast_jSerialComm_SerialPort_MARK_PARITY) ? (PARENB | CMSPAR | PARODD) : (PARENB | CMSPAR);
// Clear any serial port flags
fcntl(serialPortFD, F_SETFL, 0);
if (isatty(serialPortFD))
fcntl(serialPortFD, F_SETFL, 0);
// Set raw-mode to allow the use of tcsetattr() and ioctl()
tcgetattr(serialPortFD, &options);
// Set raw-mode to allow the use of ioctl()
if (isatty(serialPortFD))
ioctl(serialPortFD, TCGETS, &options);
cfmakeraw(&options);
// Set updated port parameters
@ -175,8 +185,9 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
}
// Apply changes
int retVal = tcsetattr(serialPortFD, TCSANOW, &options);
ioctl(serialPortFD, TIOCEXCL); // Block non-root users from using this port
int retVal = -1;
if (isatty(serialPortFD))
retVal = ioctl(serialPortFD, TCSETS, &options);
if (baudRateCode == 0) // Set custom baud rate
setBaudRate(serialPortFD, baudRate);
return ((retVal == 0) ? JNI_TRUE : JNI_FALSE);
@ -198,14 +209,17 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configFlowCo
tcflag_t XonXoffOutEnabled = ((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_XONXOFF_OUT_ENABLED) > 0) ? IXON : 0;
// Retrieve existing port configuration
tcgetattr(serialPortFD, &options);
if (isatty(serialPortFD))
ioctl(serialPortFD, TCGETS, &options);
// Set updated port parameters
options.c_cflag |= CTSRTSEnabled;
options.c_iflag |= XonXoffInEnabled | XonXoffOutEnabled;
// Apply changes
int retVal = tcsetattr(serialPortFD, TCSANOW, &options);
int retVal = -1;
if (isatty(serialPortFD))
retVal = ioctl(serialPortFD, TCSETS, &options);
if (baudRateCode == 0) // Set custom baud rate
setBaudRate(serialPortFD, baudRate);
return ((retVal == 0) ? JNI_TRUE : JNI_FALSE);
@ -223,8 +237,11 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
// Retrieve existing port configuration
struct termios options = { 0 };
tcgetattr(serialPortFD, &options);
if (isatty(serialPortFD))
ioctl(serialPortFD, TCGETS, &options);
int flags = fcntl(serialPortFD, F_GETFL);
if (flags == -1)
return JNI_FALSE;
// Set updated port timeouts
if (((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_READ_SEMI_BLOCKING) > 0) && (readTimeout > 0)) // Read Semi-blocking with timeout
@ -265,8 +282,9 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
}
// Apply changes
fcntl(serialPortFD, F_SETFL, flags);
int retVal = tcsetattr(serialPortFD, TCSANOW, &options);
int retVal = fcntl(serialPortFD, F_SETFL, flags);
if ((retVal != -1) && isatty(serialPortFD))
retVal = ioctl(serialPortFD, TCSETS, &options);
if (baudRateCode == 0) // Set custom baud rate
setBaudRate(serialPortFD, baudRate);
return ((retVal == 0) ? JNI_TRUE : JNI_FALSE);
@ -283,24 +301,27 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configEventF
int eventsToMonitor = (*env)->GetIntField(env, obj, eventFlagsField);
// Change read timeouts if we are monitoring data received
jboolean retVal;
if ((eventsToMonitor & com_fazecast_jSerialComm_SerialPort_LISTENING_EVENT_DATA_RECEIVED) > 0)
{
struct termios options = { 0 };
tcgetattr(serialPortFD, &options);
ioctl(serialPortFD, TCGETS, &options);
int flags = fcntl(serialPortFD, F_GETFL);
if (flags == -1)
return JNI_FALSE;
flags &= ~O_NONBLOCK;
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
fcntl(serialPortFD, F_SETFL, flags);
tcsetattr(serialPortFD, TCSANOW, &options);
retVal = ((fcntl(serialPortFD, F_SETFL, flags) == -1) || (ioctl(serialPortFD, TCSETS, &options) == -1)) ?
JNI_FALSE : JNI_TRUE;
if (baudRateCode == 0) // Set custom baud rate
setBaudRate(serialPortFD, baudRate);
}
else
Java_com_fazecast_jSerialComm_SerialPort_configTimeouts(env, obj, serialPortFD);
retVal = Java_com_fazecast_jSerialComm_SerialPort_configTimeouts(env, obj, serialPortFD);
// Apply changes
return JNI_TRUE;
return retVal;
}
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNIEnv *env, jobject obj, jlong serialPortFD)
@ -315,7 +336,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNI
FD_SET(serialPortFD, &waitingSet);
// Wait for a serial port event
int retVal = select(serialPortFD + 1, &waitingSet, NULL, NULL, &timeout);
int retVal;
do { retVal = select(serialPortFD + 1, &waitingSet, NULL, NULL, &timeout); } while ((retVal < 0) && (errno == EINTR));
if (retVal <= 0)
return 0;
return (FD_ISSET(serialPortFD, &waitingSet)) ? com_fazecast_jSerialComm_SerialPort_LISTENING_EVENT_DATA_AVAILABLE : 0;
@ -326,7 +348,7 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNat
// Close port
if (serialPortFD <= 0)
return JNI_TRUE;
close(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
@ -359,10 +381,11 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
// While there are more bytes we are supposed to read
while (bytesRemaining > 0)
{
if ((numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining)) == -1)
do { numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining); } while ((numBytesRead < 0) && (errno == EINTR));
if (numBytesRead == -1)
{
// Problem reading, close port
close(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
@ -389,10 +412,11 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
// While there are more bytes we are supposed to read and the timeout has not elapsed
do
{
if ((numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining)) == -1)
do { numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining); } while ((numBytesRead < 0) && (errno == EINTR));
if (numBytesRead == -1)
{
// Problem reading, close port
close(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
@ -411,10 +435,11 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
else // Semi- or non-blocking specified
{
// Read from port
if ((numBytesRead = read(serialPortFD, readBuffer, bytesToRead)) == -1)
do { numBytesRead = read(serialPortFD, readBuffer, bytesToRead); } while ((numBytesRead < 0) && (errno == EINTR));
if (numBytesRead == -1)
{
// Problem reading, close port
close(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
@ -437,10 +462,11 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
int numBytesWritten;
// Write to port
if ((numBytesWritten = write(serialPortFD, writeBuffer, bytesToWrite)) == -1)
do { numBytesWritten = write(serialPortFD, writeBuffer, bytesToWrite); } while ((numBytesWritten < 0) && (errno == EINTR));
if (numBytesWritten == -1)
{
// Problem writing, close port
close(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);

View File

@ -87,6 +87,14 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_uninitializeLibr
JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative
(JNIEnv *, jobject);
/*
* Class: com_fazecast_jSerialComm_SerialPort
* Method: associateNativeHandle
* Signature: (J)Z
*/
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_associateNativeHandle
(JNIEnv *, jobject, jlong);
/*
* Class: com_fazecast_jSerialComm_SerialPort
* Method: closePortNative

View File

@ -2,7 +2,7 @@
* SerialPort_Linux.c
*
* Created on: Feb 25, 2012
* Last Updated on: May 04, 2015
* Last Updated on: Oct 09, 2015
* Author: Will Hedgecock
*
* Copyright (C) 2012-2015 Fazecast, Inc.
@ -126,7 +126,9 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
else
{
// Close the port if there was a problem setting the parameters
close(serialPortFD);
ioctl(serialPortFD, TIOCNXCL);
tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
}
@ -179,7 +181,7 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
// Apply changes
int retVal = tcsetattr(serialPortFD, TCSANOW, &options);
ioctl(serialPortFD, TIOCEXCL); // Block non-root users from using this port
ioctl(serialPortFD, TIOCEXCL); // Block non-root users from opening this port
if (baudRateCode == 0) // Set custom baud rate
setBaudRate(serialPortFD, baudRate);
return ((retVal == 0) ? JNI_TRUE : JNI_FALSE);
@ -228,6 +230,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
struct termios options = { 0 };
tcgetattr(serialPortFD, &options);
int flags = fcntl(serialPortFD, F_GETFL);
if (flags == -1)
return JNI_FALSE;
// Set updated port timeouts
if (((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_READ_SEMI_BLOCKING) > 0) && (readTimeout > 0)) // Read Semi-blocking with timeout
@ -268,8 +272,9 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
}
// Apply changes
fcntl(serialPortFD, F_SETFL, flags);
int retVal = tcsetattr(serialPortFD, TCSANOW, &options);
int retVal = fcntl(serialPortFD, F_SETFL, flags);
if (retVal != -1)
retVal = tcsetattr(serialPortFD, TCSANOW, &options);
if (baudRateCode == 0) // Set custom baud rate
setBaudRate(serialPortFD, baudRate);
return ((retVal == 0) ? JNI_TRUE : JNI_FALSE);
@ -286,24 +291,27 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configEventF
int eventsToMonitor = (*env)->GetIntField(env, obj, eventFlagsField);
// Change read timeouts if we are monitoring data received
jboolean retVal;
if ((eventsToMonitor & com_fazecast_jSerialComm_SerialPort_LISTENING_EVENT_DATA_RECEIVED) > 0)
{
struct termios options = { 0 };
tcgetattr(serialPortFD, &options);
int flags = fcntl(serialPortFD, F_GETFL);
if (flags == -1)
return JNI_FALSE;
flags &= ~O_NONBLOCK;
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
fcntl(serialPortFD, F_SETFL, flags);
tcsetattr(serialPortFD, TCSANOW, &options);
retVal = ((fcntl(serialPortFD, F_SETFL, flags) == -1) || (tcsetattr(serialPortFD, TCSANOW, &options) == -1)) ?
JNI_FALSE : JNI_TRUE;
if (baudRateCode == 0) // Set custom baud rate
setBaudRate(serialPortFD, baudRate);
}
else
Java_com_fazecast_jSerialComm_SerialPort_configTimeouts(env, obj, serialPortFD);
retVal = Java_com_fazecast_jSerialComm_SerialPort_configTimeouts(env, obj, serialPortFD);
// Apply changes
return JNI_TRUE;
return retVal;
}
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNIEnv *env, jobject obj, jlong serialPortFD)
@ -330,7 +338,11 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNat
// Close port
if (serialPortFD <= 0)
return JNI_TRUE;
close(serialPortFD);
// Allow others to open this port
ioctl(serialPortFD, TIOCNXCL);
tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
@ -366,8 +378,10 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
do { numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining); } while ((numBytesRead < 0) && (errno == EINTR));
if (numBytesRead == -1)
{
// Problem reading, close port
close(serialPortFD);
// Problem reading, allow others to open the port and close it ourselves
ioctl(serialPortFD, TIOCNXCL);
tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
@ -397,8 +411,10 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
do { numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining); } while ((numBytesRead < 0) && (errno == EINTR));
if (numBytesRead == -1)
{
// Problem reading, close port
close(serialPortFD);
// Problem reading, allow others to open the port and close it ourselves
ioctl(serialPortFD, TIOCNXCL);
tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
@ -420,8 +436,10 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
do { numBytesRead = read(serialPortFD, readBuffer, bytesToRead); } while ((numBytesRead < 0) && (errno == EINTR));
if (numBytesRead == -1)
{
// Problem reading, close port
close(serialPortFD);
// Problem reading, allow others to open the port and close it ourselves
ioctl(serialPortFD, TIOCNXCL);
tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
@ -447,8 +465,10 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
do { numBytesWritten = write(serialPortFD, writeBuffer, bytesToWrite); } while ((numBytesWritten < 0) && (errno == EINTR));
if (numBytesWritten == -1)
{
// Problem writing, close port
close(serialPortFD);
// Problem writing, allow others to open the port and close it ourselves
ioctl(serialPortFD, TIOCNXCL);
tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);

View File

@ -2,7 +2,7 @@
* SerialPort_OSX.c
*
* Created on: Feb 25, 2012
* Last Updated on: July 1, 2015
* Last Updated on: Oct 09, 2015
* Author: Will Hedgecock
*
* Copyright (C) 2012-2015 Fazecast, Inc.
@ -177,7 +177,9 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
else
{
// Close the port if there was a problem setting the parameters
close(serialPortFD);
ioctl(serialPortFD, TIOCNXCL);
tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
}
@ -273,6 +275,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
struct termios options;
tcgetattr(serialPortFD, &options);
int flags = fcntl(serialPortFD, F_GETFL);
if (flags == -1)
return JNI_FALSE;
// Set updated port timeouts
if (((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_READ_SEMI_BLOCKING) > 0) && (readTimeout > 0)) // Read Semi-blocking with timeout
@ -313,8 +317,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
}
// Apply changes
fcntl(serialPortFD, F_SETFL, flags);
return (tcsetattr(serialPortFD, TCSANOW, &options) == 0) ? JNI_TRUE : JNI_FALSE;
int retVal = fcntl(serialPortFD, F_SETFL, flags);
return ((retVal != -1) && (tcsetattr(serialPortFD, TCSANOW, &options) == 0)) ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configEventFlags(JNIEnv *env, jobject obj, jlong serialPortFD)
@ -332,11 +336,13 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configEventF
struct termios options;
tcgetattr(serialPortFD, &options);
int flags = fcntl(serialPortFD, F_GETFL);
if (flags == -1)
return JNI_FALSE;
flags &= ~O_NONBLOCK;
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
fcntl(serialPortFD, F_SETFL, flags);
retVal = (tcsetattr(serialPortFD, TCSANOW, &options) == 0) ? JNI_TRUE : JNI_FALSE;
retVal = ((fcntl(serialPortFD, F_SETFL, flags) != -1) && (tcsetattr(serialPortFD, TCSANOW, &options) != -1)) ?
JNI_TRUE : JNI_FALSE;
}
else
retVal = Java_com_fazecast_jSerialComm_SerialPort_configTimeouts(env, obj, serialPortFD);
@ -368,8 +374,11 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNat
// Close port
if (serialPortFD <= 0)
return JNI_TRUE;
// Allow others to open the port and close it ourselves
ioctl(serialPortFD, TIOCNXCL);
tcdrain(serialPortFD);
close(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
@ -405,8 +414,10 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
do { numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining); } while ((numBytesRead < 0) && (errno == EINTR));
if (numBytesRead == -1)
{
// Problem reading, close port
close(serialPortFD);
// Problem reading, allow others to open the port and close it ourselves
ioctl(serialPortFD, TIOCNXCL);
tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
@ -436,8 +447,10 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
do { numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining); } while ((numBytesRead < 0) && (errno == EINTR));
if (numBytesRead == -1)
{
// Problem reading, close port
close(serialPortFD);
// Problem reading, allow others to open the port and close it ourselves
ioctl(serialPortFD, TIOCNXCL);
tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
@ -459,8 +472,10 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
do { numBytesRead = read(serialPortFD, readBuffer, bytesToRead); } while ((numBytesRead < 0) && (errno == EINTR));
if (numBytesRead == -1)
{
// Problem reading, close port
close(serialPortFD);
// Problem reading, allow others to open the port and close it ourselves
ioctl(serialPortFD, TIOCNXCL);
tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);
@ -486,8 +501,10 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
do { numBytesWritten = write(serialPortFD, writeBuffer, bytesToWrite); } while ((numBytesWritten < 0) && (errno == EINTR));
if (numBytesWritten == -1)
{
// Problem writing, close port
close(serialPortFD);
// Problem writing, allow others to open the port and close it ourselves
ioctl(serialPortFD, TIOCNXCL);
tcdrain(serialPortFD);
while ((close(serialPortFD) == -1) && (errno != EBADF));
serialPortFD = -1;
(*env)->SetLongField(env, obj, serialPortFdField, -1l);
(*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE);

View File

@ -263,7 +263,8 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
else
{
// Close the port if there was a problem setting the parameters
CloseHandle(serialPortHandle);
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
while (!CloseHandle(serialPortHandle));
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetBooleanField(obj, isOpenedField, JNI_FALSE);
}
@ -474,7 +475,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNI
if (GetLastError() != ERROR_IO_PENDING) // Problem occurred
{
// Problem reading, close port
CloseHandle(serialPortHandle);
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
while (!CloseHandle(serialPortHandle));
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, serialPortHandleField, -1l);
env->SetBooleanField(obj, isOpenedField, JNI_FALSE);
@ -498,12 +500,12 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNat
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
// Close port
BOOL retVal = CloseHandle(serialPortHandle);
while (!CloseHandle(serialPortHandle));
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, serialPortHandleField, -1l);
env->SetBooleanField(obj, isOpenedField, JNI_FALSE);
return (retVal == 0) ? JNI_FALSE : JNI_TRUE;
return JNI_TRUE;
}
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAvailable(JNIEnv *env, jobject obj, jlong serialPortFD)
@ -542,7 +544,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
if (GetLastError() != ERROR_IO_PENDING) // Problem occurred
{
// Problem reading, close port
CloseHandle(serialPortHandle);
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
while (!CloseHandle(serialPortHandle));
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, serialPortHandleField, -1l);
env->SetBooleanField(obj, isOpenedField, JNI_FALSE);
@ -550,7 +553,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
else if ((result = GetOverlappedResult(serialPortHandle, &overlappedStruct, &numBytesRead, TRUE)) == FALSE)
{
// Problem reading, close port
CloseHandle(serialPortHandle);
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
while (!CloseHandle(serialPortHandle));
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, serialPortHandleField, -1l);
env->SetBooleanField(obj, isOpenedField, JNI_FALSE);
@ -586,7 +590,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
if (GetLastError() != ERROR_IO_PENDING)
{
// Problem writing, close port
CloseHandle(serialPortHandle);
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
while (!CloseHandle(serialPortHandle));
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, serialPortHandleField, -1l);
env->SetBooleanField(obj, isOpenedField, JNI_FALSE);
@ -594,7 +599,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
else if ((result = GetOverlappedResult(serialPortHandle, &overlappedStruct, &numBytesWritten, TRUE)) == FALSE)
{
// Problem reading, close port
CloseHandle(serialPortHandle);
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
while (!CloseHandle(serialPortHandle));
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, serialPortHandleField, -1l);
env->SetBooleanField(obj, isOpenedField, JNI_FALSE);

View File

@ -31,7 +31,7 @@ import java.util.EventListener;
* This interface must be implemented to enable simple event-based serial port I/O.
*
* @author Will Hedgecock &lt;will.hedgecock@fazecast.com&gt;
* @version 1.3.8
* @version 1.3.9
* @see java.util.EventListener
*/
public interface SerialPortDataListener extends EventListener

View File

@ -31,7 +31,7 @@ import java.util.EventObject;
* This class describes an asynchronous serial port event.
*
* @author Will Hedgecock &lt;will.hedgecock@fazecast.com&gt;
* @version 1.3.8
* @version 1.3.9
* @see java.util.EventObject
*/
public final class SerialPortEvent extends EventObject

View File

@ -31,7 +31,7 @@ package com.fazecast.jSerialComm;
* <i>Note</i>: Using this interface will negate any serial port read timeout settings since they make no sense in an asynchronous context.
*
* @author Will Hedgecock &lt;will.hedgecock@fazecast.com&gt;
* @version 1.3.8
* @version 1.3.9
* @see com.fazecast.jSerialComm.SerialPortDataListener
* @see java.util.EventListener
*/

View File

@ -32,7 +32,7 @@ import java.util.Scanner;
* This class provides a test case for the jSerialComm library.
*
* @author Will Hedgecock &lt;will.hedgecock@gmail.com&gt;
* @version 1.3.8
* @version 1.3.9
* @see java.io.InputStream
* @see java.io.OutputStream
*/