diff --git a/src/main/c/Android/jni/SerialPort_Android.c b/src/main/c/Android/jni/SerialPort_Android.c index c789a3b..61fcdd0 100644 --- a/src/main/c/Android/jni/SerialPort_Android.c +++ b/src/main/c/Android/jni/SerialPort_Android.c @@ -55,7 +55,7 @@ jfieldID serialPortFdField; jfieldID comPortField; jfieldID friendlyNameField; jfieldID portDescriptionField; -jfieldID isOpenedField; +jfieldID eventListenerRunningField; jfieldID disableConfigField; jfieldID isDtrEnabledField; jfieldID isRtsEnabledField; @@ -114,7 +114,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar comPortField = (*env)->GetFieldID(env, serialCommClass, "comPort", "Ljava/lang/String;"); friendlyNameField = (*env)->GetFieldID(env, serialCommClass, "friendlyName", "Ljava/lang/String;"); portDescriptionField = (*env)->GetFieldID(env, serialCommClass, "portDescription", "Ljava/lang/String;"); - isOpenedField = (*env)->GetFieldID(env, serialCommClass, "isOpened", "Z"); + eventListenerRunningField = (*env)->GetFieldID(env, serialCommClass, "eventListenerRunning", "Z"); disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z"); isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z"); isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z"); @@ -172,14 +172,13 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative( // Configure the port parameters and timeouts if (Java_com_fazecast_jSerialComm_SerialPort_configPort(env, obj, serialPortFD)) - (*env)->SetBooleanField(env, obj, isOpenedField, JNI_TRUE); + (*env)->SetLongField(env, obj, serialPortHandleField, serialPortFD); else { // Close the port if there was a problem setting the parameters tcdrain(serialPortFD); while ((close(serialPortFD) == -1) && (errno != EBADF)); serialPortFD = -1; - (*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE); } } @@ -435,7 +434,6 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNat // Ensure that the port is open if (serialPortFD <= 0) return JNI_TRUE; - (*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE); // Force the port to enter non-blocking mode to ensure that any current reads return struct termios options = {0}; @@ -460,9 +458,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAvailable(J { // Problem detected, close the port tcdrain(serialPortFD); - while (((*env)->GetBooleanField(env, obj, isOpenedField)) && (close(serialPortFD) == -1) && (errno != EBADF)); + while ((close(serialPortFD) == -1) && (errno != EBADF)); (*env)->SetLongField(env, obj, serialPortFdField, -1l); - (*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE); } return numBytesAvailable; @@ -497,10 +494,9 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv if ((numBytesRead == -1) || ((numBytesRead == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1))) { // Problem reading, close port - while (((*env)->GetBooleanField(env, obj, isOpenedField)) && (close(serialPortFD) == -1) && (errno != EBADF)); + while ((close(serialPortFD) == -1) && (errno != EBADF)); serialPortFD = -1; (*env)->SetLongField(env, obj, serialPortFdField, -1l); - (*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE); break; } @@ -528,10 +524,9 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv if ((numBytesRead == -1) || ((numBytesRead == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1))) { // Problem reading, close port - while (((*env)->GetBooleanField(env, obj, isOpenedField)) && (close(serialPortFD) == -1) && (errno != EBADF)); + while ((close(serialPortFD) == -1) && (errno != EBADF)); serialPortFD = -1; (*env)->SetLongField(env, obj, serialPortFdField, -1l); - (*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE); break; } @@ -551,10 +546,9 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv if ((numBytesRead == -1) || ((numBytesRead == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1))) { // Problem reading, close port - while (((*env)->GetBooleanField(env, obj, isOpenedField)) && (close(serialPortFD) == -1) && (errno != EBADF)); + while ((close(serialPortFD) == -1) && (errno != EBADF)); serialPortFD = -1; (*env)->SetLongField(env, obj, serialPortFdField, -1l); - (*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE); } else numBytesReadTotal = numBytesRead; @@ -563,7 +557,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv // Return number of bytes read if successful (*env)->SetByteArrayRegion(env, buffer, offset, numBytesReadTotal, (jbyte*)readBuffer); free(readBuffer); - return (numBytesRead == -1) || !((*env)->GetBooleanField(env, obj, isOpenedField)) ? -1 : numBytesReadTotal; + return (numBytesRead == -1) || (serialPortFD == -1) ? -1 : numBytesReadTotal; } JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEnv *env, jobject obj, jlong serialPortFD, jbyteArray buffer, jlong bytesToWrite, jlong offset) @@ -580,10 +574,9 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn { // Problem writing, close the port ioctl(serialPortFD, TCSBRK, 1); - while (((*env)->GetBooleanField(env, obj, isOpenedField)) && (close(serialPortFD) == -1) && (errno != EBADF)); + while ((close(serialPortFD) == -1) && (errno != EBADF)); serialPortFD = -1; (*env)->SetLongField(env, obj, serialPortFdField, -1l); - (*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE); } // Wait until all bytes were written in write-blocking mode diff --git a/src/main/c/Posix/SerialPort_Posix.c b/src/main/c/Posix/SerialPort_Posix.c index 60b3081..c3bad8e 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: Feb 18, 2020 + * Last Updated on: Feb 19, 2020 * Author: Will Hedgecock * * Copyright (C) 2012-2020 Fazecast, Inc. @@ -53,7 +53,7 @@ jfieldID serialPortFdField; jfieldID comPortField; jfieldID friendlyNameField; jfieldID portDescriptionField; -jfieldID isOpenedField; +jfieldID eventListenerRunningField; jfieldID disableConfigField; jfieldID isDtrEnabledField; jfieldID isRtsEnabledField; @@ -218,7 +218,7 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar comPortField = (*env)->GetFieldID(env, serialCommClass, "comPort", "Ljava/lang/String;"); friendlyNameField = (*env)->GetFieldID(env, serialCommClass, "friendlyName", "Ljava/lang/String;"); portDescriptionField = (*env)->GetFieldID(env, serialCommClass, "portDescription", "Ljava/lang/String;"); - isOpenedField = (*env)->GetFieldID(env, serialCommClass, "isOpened", "Z"); + eventListenerRunningField = (*env)->GetFieldID(env, serialCommClass, "eventListenerRunning", "Z"); disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z"); isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z"); isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z"); @@ -259,7 +259,9 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative( // Ensure that multiple root users cannot access the device simultaneously if (flock(serialPortFD, LOCK_EX | LOCK_NB) == -1) { - while ((close(serialPortFD) == -1) && (errno == EINTR)); + tcdrain(serialPortFD); + while ((close(serialPortFD) == -1) && (errno == EINTR)) + errno = 0; serialPortFD = -1; } else @@ -284,14 +286,14 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative( // Configure the port parameters and timeouts if (Java_com_fazecast_jSerialComm_SerialPort_configPort(env, obj, serialPortFD)) - (*env)->SetBooleanField(env, obj, isOpenedField, JNI_TRUE); + (*env)->SetLongField(env, obj, serialPortFdField, serialPortFD); else { // Close the port if there was a problem setting the parameters tcdrain(serialPortFD); - while ((close(serialPortFD) == -1) && (errno == EINTR)); + while ((close(serialPortFD) == -1) && (errno == EINTR)) + errno = 0; serialPortFD = -1; - (*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE); } } } @@ -499,7 +501,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNI struct pollfd waitingSet = { serialPortFD, POLLIN, 0 }; // Wait for a serial port event - if (poll(&waitingSet, 1, 1000) <= 0) + if (poll(&waitingSet, 1, 500) <= 0) return 0; return (waitingSet.revents & POLLIN) ? com_fazecast_jSerialComm_SerialPort_LISTENING_EVENT_DATA_AVAILABLE : 0; } @@ -523,10 +525,9 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNat // Close the port flock(serialPortFD, LOCK_UN | LOCK_NB); - while (((*env)->GetBooleanField(env, obj, isOpenedField)) && (close(serialPortFD) == -1) && (errno == EINTR)) + while ((close(serialPortFD) == -1) && (errno == EINTR)) errno = 0; (*env)->SetLongField(env, obj, serialPortFdField, -1l); - (*env)->SetBooleanField(env, obj, isOpenedField, JNI_FALSE); return JNI_TRUE; } @@ -569,6 +570,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv { // Problem reading, close the port Java_com_fazecast_jSerialComm_SerialPort_closePortNative(env, obj, serialPortFD); + serialPortFD = -1; break; } @@ -597,6 +599,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv { // Problem reading, close the port Java_com_fazecast_jSerialComm_SerialPort_closePortNative(env, obj, serialPortFD); + serialPortFD = -1; break; } @@ -616,6 +619,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv { // Problem reading, close the port Java_com_fazecast_jSerialComm_SerialPort_closePortNative(env, obj, serialPortFD); + serialPortFD = -1; } else numBytesReadTotal = numBytesRead; @@ -624,7 +628,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv // Return number of bytes read if successful (*env)->SetByteArrayRegion(env, buffer, offset, numBytesReadTotal, (jbyte*)readBuffer); free(readBuffer); - return (numBytesRead == -1) || !((*env)->GetBooleanField(env, obj, isOpenedField)) ? -1 : numBytesReadTotal; + return ((numBytesRead == -1) || (serialPortFD == -1)) ? -1 : numBytesReadTotal; } JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEnv *env, jobject obj, jlong serialPortFD, jbyteArray buffer, jlong bytesToWrite, jlong offset)