Fixed JNI crash when calling native functions after port has already closed.
This commit is contained in:
parent
56586964d4
commit
7993eeb7a0
|
@ -101,6 +101,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
|
||||||
struct serial_struct serialInfo;
|
struct serial_struct serialInfo;
|
||||||
jclass serialCommClass = env->GetObjectClass(obj);
|
jclass serialCommClass = env->GetObjectClass(obj);
|
||||||
int portFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
int portFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
|
if (portFD <= 0)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
// Set raw-mode to allow the use of tcsetattr() and ioctl()
|
// Set raw-mode to allow the use of tcsetattr() and ioctl()
|
||||||
fcntl(portFD, F_SETFL, 0);
|
fcntl(portFD, F_SETFL, 0);
|
||||||
|
@ -146,6 +148,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configFlowCo
|
||||||
struct termios options;
|
struct termios options;
|
||||||
jclass serialCommClass = env->GetObjectClass(obj);
|
jclass serialCommClass = env->GetObjectClass(obj);
|
||||||
int portFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
int portFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
|
if (portFD <= 0)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
// Get port parameters from Java class
|
// Get port parameters from Java class
|
||||||
int flowControl = env->GetIntField(obj, env->GetFieldID(serialCommClass, "flowControl", "I"));
|
int flowControl = env->GetIntField(obj, env->GetFieldID(serialCommClass, "flowControl", "I"));
|
||||||
|
@ -175,6 +179,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
|
||||||
int serialFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
int serialFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
int timeoutMode = env->GetIntField(obj, env->GetFieldID(serialCommClass, "timeoutMode", "I"));
|
int timeoutMode = env->GetIntField(obj, env->GetFieldID(serialCommClass, "timeoutMode", "I"));
|
||||||
int readTimeout = env->GetIntField(obj, env->GetFieldID(serialCommClass, "readTimeout", "I"));
|
int readTimeout = env->GetIntField(obj, env->GetFieldID(serialCommClass, "readTimeout", "I"));
|
||||||
|
if (serialFD <= 0)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
// Retrieve existing port configuration
|
// Retrieve existing port configuration
|
||||||
struct termios options;
|
struct termios options;
|
||||||
|
@ -222,6 +228,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configEventF
|
||||||
{
|
{
|
||||||
jclass serialCommClass = env->GetObjectClass(obj);
|
jclass serialCommClass = env->GetObjectClass(obj);
|
||||||
int serialFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
int serialFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
|
if (serialFD <= 0)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
// Get event flags from Java class
|
// Get event flags from Java class
|
||||||
int eventsToMonitor = env->GetIntField(obj, env->GetFieldID(serialCommClass, "eventFlags", "I"));
|
int eventsToMonitor = env->GetIntField(obj, env->GetFieldID(serialCommClass, "eventFlags", "I"));
|
||||||
|
@ -249,6 +257,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNI
|
||||||
{
|
{
|
||||||
jclass serialCommClass = env->GetObjectClass(obj);
|
jclass serialCommClass = env->GetObjectClass(obj);
|
||||||
int serialFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
int serialFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
|
if (serialFD <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
// Initialize the waiting set and the timeouts
|
// Initialize the waiting set and the timeouts
|
||||||
struct timeval timeout = { 1, 0 };
|
struct timeval timeout = { 1, 0 };
|
||||||
|
@ -267,6 +277,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNat
|
||||||
{
|
{
|
||||||
// Close port
|
// Close port
|
||||||
int portFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
|
int portFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
|
||||||
|
if (portFD <= 0)
|
||||||
|
return JNI_TRUE;
|
||||||
close(portFD);
|
close(portFD);
|
||||||
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), -1l);
|
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), -1l);
|
||||||
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
|
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
|
||||||
|
@ -279,7 +291,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAvailable(J
|
||||||
int serialPortFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
|
int serialPortFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
|
||||||
int numBytesAvailable = -1;
|
int numBytesAvailable = -1;
|
||||||
|
|
||||||
if (serialPortFD != -1)
|
if (serialPortFD > 0)
|
||||||
ioctl(serialPortFD, FIONREAD, &numBytesAvailable);
|
ioctl(serialPortFD, FIONREAD, &numBytesAvailable);
|
||||||
|
|
||||||
return numBytesAvailable;
|
return numBytesAvailable;
|
||||||
|
|
|
@ -116,6 +116,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
|
||||||
struct termios options;
|
struct termios options;
|
||||||
jclass serialCommClass = env->GetObjectClass(obj);
|
jclass serialCommClass = env->GetObjectClass(obj);
|
||||||
int portFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
int portFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
|
if (portFD <= 0)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
// Set raw-mode to allow the use of tcsetattr() and ioctl()
|
// Set raw-mode to allow the use of tcsetattr() and ioctl()
|
||||||
fcntl(portFD, F_SETFL, 0);
|
fcntl(portFD, F_SETFL, 0);
|
||||||
|
@ -152,6 +154,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configFlowCo
|
||||||
struct termios options;
|
struct termios options;
|
||||||
jclass serialCommClass = env->GetObjectClass(obj);
|
jclass serialCommClass = env->GetObjectClass(obj);
|
||||||
int portFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
int portFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
|
if (portFD <= 0)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
// Get port parameters from Java class
|
// Get port parameters from Java class
|
||||||
int flowControl = env->GetIntField(obj, env->GetFieldID(serialCommClass, "flowControl", "I"));
|
int flowControl = env->GetIntField(obj, env->GetFieldID(serialCommClass, "flowControl", "I"));
|
||||||
|
@ -181,6 +185,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
|
||||||
int serialFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
int serialFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
int timeoutMode = env->GetIntField(obj, env->GetFieldID(serialCommClass, "timeoutMode", "I"));
|
int timeoutMode = env->GetIntField(obj, env->GetFieldID(serialCommClass, "timeoutMode", "I"));
|
||||||
int readTimeout = env->GetIntField(obj, env->GetFieldID(serialCommClass, "readTimeout", "I"));
|
int readTimeout = env->GetIntField(obj, env->GetFieldID(serialCommClass, "readTimeout", "I"));
|
||||||
|
if (serialFD <= 0)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
// Retrieve existing port configuration
|
// Retrieve existing port configuration
|
||||||
struct termios options;
|
struct termios options;
|
||||||
|
@ -228,6 +234,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configEventF
|
||||||
{
|
{
|
||||||
jclass serialCommClass = env->GetObjectClass(obj);
|
jclass serialCommClass = env->GetObjectClass(obj);
|
||||||
int serialFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
int serialFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
|
if (serialFD <= 0)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
// Get event flags from Java class
|
// Get event flags from Java class
|
||||||
int eventsToMonitor = env->GetIntField(obj, env->GetFieldID(serialCommClass, "eventFlags", "I"));
|
int eventsToMonitor = env->GetIntField(obj, env->GetFieldID(serialCommClass, "eventFlags", "I"));
|
||||||
|
@ -255,6 +263,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNI
|
||||||
{
|
{
|
||||||
jclass serialCommClass = env->GetObjectClass(obj);
|
jclass serialCommClass = env->GetObjectClass(obj);
|
||||||
int serialFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
int serialFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
|
if (serialFD <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
// Initialize the waiting set and the timeouts
|
// Initialize the waiting set and the timeouts
|
||||||
struct timeval timeout = { 1, 0 };
|
struct timeval timeout = { 1, 0 };
|
||||||
|
@ -273,6 +283,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNat
|
||||||
{
|
{
|
||||||
// Close port
|
// Close port
|
||||||
int portFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
|
int portFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
|
||||||
|
if (portFD <= 0)
|
||||||
|
return JNI_TRUE;
|
||||||
close(portFD);
|
close(portFD);
|
||||||
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), -1l);
|
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), -1l);
|
||||||
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
|
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
|
||||||
|
@ -285,7 +297,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAvailable(J
|
||||||
int serialPortFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
|
int serialPortFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
|
||||||
int numBytesAvailable = -1;
|
int numBytesAvailable = -1;
|
||||||
|
|
||||||
if (serialPortFD != -1)
|
if (serialPortFD > 0)
|
||||||
ioctl(serialPortFD, FIONREAD, &numBytesAvailable);
|
ioctl(serialPortFD, FIONREAD, &numBytesAvailable);
|
||||||
|
|
||||||
return numBytesAvailable;
|
return numBytesAvailable;
|
||||||
|
|
|
@ -223,9 +223,11 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
|
||||||
DCB dcbSerialParams = {0};
|
DCB dcbSerialParams = {0};
|
||||||
dcbSerialParams.DCBlength = sizeof(DCB);
|
dcbSerialParams.DCBlength = sizeof(DCB);
|
||||||
jclass serialCommClass = env->GetObjectClass(obj);
|
jclass serialCommClass = env->GetObjectClass(obj);
|
||||||
|
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
|
if (serialPortHandle == INVALID_HANDLE_VALUE)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
// Get port parameters from Java class
|
// Get port parameters from Java class
|
||||||
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
|
||||||
DWORD baudRate = (DWORD)env->GetIntField(obj, env->GetFieldID(serialCommClass, "baudRate", "I"));
|
DWORD baudRate = (DWORD)env->GetIntField(obj, env->GetFieldID(serialCommClass, "baudRate", "I"));
|
||||||
BYTE byteSize = (BYTE)env->GetIntField(obj, env->GetFieldID(serialCommClass, "dataBits", "I"));
|
BYTE byteSize = (BYTE)env->GetIntField(obj, env->GetFieldID(serialCommClass, "dataBits", "I"));
|
||||||
int stopBitsInt = env->GetIntField(obj, env->GetFieldID(serialCommClass, "stopBits", "I"));
|
int stopBitsInt = env->GetIntField(obj, env->GetFieldID(serialCommClass, "stopBits", "I"));
|
||||||
|
@ -257,6 +259,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configFlowCo
|
||||||
dcbSerialParams.DCBlength = sizeof(DCB);
|
dcbSerialParams.DCBlength = sizeof(DCB);
|
||||||
jclass serialCommClass = env->GetObjectClass(obj);
|
jclass serialCommClass = env->GetObjectClass(obj);
|
||||||
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
|
if (serialPortHandle == INVALID_HANDLE_VALUE)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
// Get flow control parameters from Java class
|
// Get flow control parameters from Java class
|
||||||
int flowControl = env->GetIntField(obj, env->GetFieldID(serialCommClass, "flowControl", "I"));
|
int flowControl = env->GetIntField(obj, env->GetFieldID(serialCommClass, "flowControl", "I"));
|
||||||
|
@ -303,6 +307,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
|
||||||
int timeoutMode = env->GetIntField(obj, env->GetFieldID(serialCommClass, "timeoutMode", "I"));
|
int timeoutMode = env->GetIntField(obj, env->GetFieldID(serialCommClass, "timeoutMode", "I"));
|
||||||
DWORD readTimeout = (DWORD)env->GetIntField(obj, env->GetFieldID(serialCommClass, "readTimeout", "I"));
|
DWORD readTimeout = (DWORD)env->GetIntField(obj, env->GetFieldID(serialCommClass, "readTimeout", "I"));
|
||||||
DWORD writeTimeout = (DWORD)env->GetIntField(obj, env->GetFieldID(serialCommClass, "writeTimeout", "I"));
|
DWORD writeTimeout = (DWORD)env->GetIntField(obj, env->GetFieldID(serialCommClass, "writeTimeout", "I"));
|
||||||
|
if (serialHandle == INVALID_HANDLE_VALUE)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
// Set updated port timeouts
|
// Set updated port timeouts
|
||||||
timeouts.WriteTotalTimeoutMultiplier = 0;
|
timeouts.WriteTotalTimeoutMultiplier = 0;
|
||||||
|
@ -361,6 +367,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configEventF
|
||||||
{
|
{
|
||||||
jclass serialCommClass = env->GetObjectClass(obj);
|
jclass serialCommClass = env->GetObjectClass(obj);
|
||||||
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
|
if (serialPortHandle == INVALID_HANDLE_VALUE)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
// Get event flags from Java class
|
// Get event flags from Java class
|
||||||
int eventsToMonitor = env->GetIntField(obj, env->GetFieldID(serialCommClass, "eventFlags", "I"));
|
int eventsToMonitor = env->GetIntField(obj, env->GetFieldID(serialCommClass, "eventFlags", "I"));
|
||||||
|
@ -393,12 +401,14 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNI
|
||||||
{
|
{
|
||||||
jclass serialCommClass = env->GetObjectClass(obj);
|
jclass serialCommClass = env->GetObjectClass(obj);
|
||||||
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
|
||||||
|
if (serialPortHandle == INVALID_HANDLE_VALUE)
|
||||||
|
return 0;
|
||||||
OVERLAPPED overlappedStruct = {0};
|
OVERLAPPED overlappedStruct = {0};
|
||||||
overlappedStruct.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
overlappedStruct.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
if (overlappedStruct.hEvent == NULL)
|
if (overlappedStruct.hEvent == NULL)
|
||||||
{
|
{
|
||||||
CloseHandle(overlappedStruct.hEvent);
|
CloseHandle(overlappedStruct.hEvent);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for a serial port event
|
// Wait for a serial port event
|
||||||
|
@ -427,6 +437,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNat
|
||||||
{
|
{
|
||||||
// Purge any outstanding port operations
|
// Purge any outstanding port operations
|
||||||
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
|
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
|
||||||
|
if (serialPortHandle == INVALID_HANDLE_VALUE)
|
||||||
|
return JNI_TRUE;
|
||||||
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
|
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
|
||||||
|
|
||||||
// Close port
|
// Close port
|
||||||
|
|
Loading…
Reference in New Issue