Check for closed port before trying to read from port

This commit is contained in:
hedgecrw85 2019-11-07 17:20:04 -06:00
parent 6d8da8a9e2
commit 5c7673c875
4 changed files with 85 additions and 47 deletions

View File

@ -2,7 +2,7 @@
* SerialPort_Windows.c * SerialPort_Windows.c
* *
* Created on: Feb 25, 2012 * Created on: Feb 25, 2012
* Last Updated on: Oct 29, 2019 * Last Updated on: Nov 07, 2019
* Author: Will Hedgecock * Author: Will Hedgecock
* *
* Copyright (C) 2012-2019 Fazecast, Inc. * Copyright (C) 2012-2019 Fazecast, Inc.
@ -638,7 +638,16 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAvailable(J
COMSTAT commInfo; COMSTAT commInfo;
if (!ClearCommError(serialPortHandle, NULL, &commInfo)) if (!ClearCommError(serialPortHandle, NULL, &commInfo))
{
// Problem detected, close port
int numRetries = 10;
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
while (env->GetBooleanField(obj, isOpenedField) && !CloseHandle(serialPortHandle) && (numRetries-- > 0));
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, serialPortHandleField, -1l);
env->SetBooleanField(obj, isOpenedField, JNI_FALSE);
return -1; return -1;
}
DWORD numBytesAvailable = commInfo.cbInQue; DWORD numBytesAvailable = commInfo.cbInQue;
return (jint)numBytesAvailable; return (jint)numBytesAvailable;
@ -660,9 +669,26 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAwaitingWri
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv *env, jobject obj, jlong serialPortFD, jbyteArray buffer, jlong bytesToRead, jlong offset) JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv *env, jobject obj, jlong serialPortFD, jbyteArray buffer, jlong bytesToRead, jlong offset)
{ {
// Retrieve the serial port handle
HANDLE serialPortHandle = (HANDLE)serialPortFD; HANDLE serialPortHandle = (HANDLE)serialPortFD;
if (serialPortHandle == INVALID_HANDLE_VALUE) if (serialPortHandle == INVALID_HANDLE_VALUE)
return -1; return -1;
// Check for a disconnected serial port
COMSTAT commInfo;
if (!ClearCommError(serialPortHandle, NULL, &commInfo))
{
// Problem detected, close port
int numRetries = 10;
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
while (env->GetBooleanField(obj, isOpenedField) && !CloseHandle(serialPortHandle) && (numRetries-- > 0));
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, serialPortHandleField, -1l);
env->SetBooleanField(obj, isOpenedField, JNI_FALSE);
return -1;
}
// Create an asynchronous result structure
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)
@ -672,12 +698,10 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
} }
char *readBuffer = (char*)malloc(bytesToRead); char *readBuffer = (char*)malloc(bytesToRead);
DWORD numBytesRead = 0; DWORD numBytesRead = 0;
BOOL result;
// Read from serial port // Read from serial port
if ((result = ReadFile(serialPortHandle, readBuffer, bytesToRead, &numBytesRead, &overlappedStruct)) == FALSE) BOOL result;
{ if (((result = ReadFile(serialPortHandle, readBuffer, bytesToRead, NULL, &overlappedStruct)) == FALSE) && (GetLastError() != ERROR_IO_PENDING))
if (GetLastError() != ERROR_IO_PENDING) // Problem occurred
{ {
// Problem reading, close port // Problem reading, close port
int numRetries = 10; int numRetries = 10;
@ -697,7 +721,6 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
env->SetLongField(obj, serialPortHandleField, -1l); env->SetLongField(obj, serialPortHandleField, -1l);
env->SetBooleanField(obj, isOpenedField, JNI_FALSE); env->SetBooleanField(obj, isOpenedField, JNI_FALSE);
} }
}
// Return number of bytes read if successful // Return number of bytes read if successful
CloseHandle(overlappedStruct.hEvent); CloseHandle(overlappedStruct.hEvent);
@ -708,9 +731,26 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEnv *env, jobject obj, jlong serialPortFD, jbyteArray buffer, jlong bytesToWrite, jlong offset) JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEnv *env, jobject obj, jlong serialPortFD, jbyteArray buffer, jlong bytesToWrite, jlong offset)
{ {
// Retrieve the serial port handle
HANDLE serialPortHandle = (HANDLE)serialPortFD; HANDLE serialPortHandle = (HANDLE)serialPortFD;
if (serialPortHandle == INVALID_HANDLE_VALUE) if (serialPortHandle == INVALID_HANDLE_VALUE)
return -1; return -1;
// Check for a disconnected serial port
COMSTAT commInfo;
if (!ClearCommError(serialPortHandle, NULL, &commInfo))
{
// Problem detected, close port
int numRetries = 10;
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
while (env->GetBooleanField(obj, isOpenedField) && !CloseHandle(serialPortHandle) && (numRetries-- > 0));
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, serialPortHandleField, -1l);
env->SetBooleanField(obj, isOpenedField, JNI_FALSE);
return -1;
}
// Create an asynchronous result structure
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)
@ -726,9 +766,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
//EscapeCommFunction(serialPortHandle, SETDTR); //EscapeCommFunction(serialPortHandle, SETDTR);
// Write to serial port // Write to serial port
if ((result = WriteFile(serialPortHandle, writeBuffer+offset, bytesToWrite, &numBytesWritten, &overlappedStruct)) == FALSE) if (((result = WriteFile(serialPortHandle, writeBuffer+offset, bytesToWrite, NULL, &overlappedStruct)) == FALSE) && (GetLastError() != ERROR_IO_PENDING))
{
if (GetLastError() != ERROR_IO_PENDING)
{ {
// Problem writing, close port // Problem writing, close port
int numRetries = 10; int numRetries = 10;
@ -740,7 +778,7 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
} }
else if ((result = GetOverlappedResult(serialPortHandle, &overlappedStruct, &numBytesWritten, TRUE)) == FALSE) else if ((result = GetOverlappedResult(serialPortHandle, &overlappedStruct, &numBytesWritten, TRUE)) == FALSE)
{ {
// Problem reading, close port // Problem writing, close port
int numRetries = 10; int numRetries = 10;
PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR); PurgeComm(serialPortHandle, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
while (env->GetBooleanField(obj, isOpenedField) && !CloseHandle(serialPortHandle) && (numRetries-- > 0)); while (env->GetBooleanField(obj, isOpenedField) && !CloseHandle(serialPortHandle) && (numRetries-- > 0));
@ -748,7 +786,6 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
env->SetLongField(obj, serialPortHandleField, -1l); env->SetLongField(obj, serialPortHandleField, -1l);
env->SetBooleanField(obj, isOpenedField, JNI_FALSE); env->SetBooleanField(obj, isOpenedField, JNI_FALSE);
} }
}
// Clear the DTR line if using RS-422 // Clear the DTR line if using RS-422
//COMSTAT commInfo; //COMSTAT commInfo;

View File

@ -5,7 +5,7 @@
* Last Updated on: Mar 25, 2016 * Last Updated on: Mar 25, 2016
* Author: Will Hedgecock * Author: Will Hedgecock
* *
* Copyright (C) 2012-2018 Fazecast, Inc. * Copyright (C) 2012-2016 Fazecast, Inc.
* *
* This file is part of jSerialComm. * This file is part of jSerialComm.
* *
@ -53,6 +53,7 @@ void push_back(struct charTupleVector* vector, const wchar_t* firstString, const
char keyExists(struct charTupleVector* vector, const wchar_t* key) char keyExists(struct charTupleVector* vector, const wchar_t* key)
{ {
// Search for a vector item with a matching key
size_t i; size_t i;
for (i = 0; i < vector->length; ++i) for (i = 0; i < vector->length; ++i)
if (wcscmp(key, vector->first[i]) == 0) if (wcscmp(key, vector->first[i]) == 0)