Created test cases and finished testing Windows functionality.

This commit is contained in:
hedgecrw85 2015-02-27 15:39:45 -06:00
parent 3ecff90412
commit 93f7d9202f
26 changed files with 339 additions and 238 deletions

29
INSTALL
View File

@ -1,20 +1,31 @@
-------------
ALL SYSTEMS
-------------
Make sure proper JDK version installed for backward compatibility, targeting Java 1.6 (JDK 1.6)
On any OS, make sure JDK_HOME is set
------------
LINUX/UNIX
------------
g++ make glibc-devel.x86_64 glibc-devel.i686 libstdc++-devel.x86_64 libstdc++-devel.i686
readlink -f /usr/bin/java : export everything up to /jre/... Ex: export JDK_HOME=/usr/lib/jvm/java-1.6.0-openjdk.x86_64
Make sure proper JDK version installed for backward compatibility, targeting Java 1.6 (JDK 1.6)
---------
WINDOWS
---------
With necessary information, like for instance
On any OS, make sure JDK_HOME is set
On Windows, first, call C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/vcvarsall.bat" x64 or x86 before building
Etc.
First, call C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/vcvarsall.bat" x64 or x86 before building
gradle eclipse
gradle build
gradle build
Located in build/lib

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -10,14 +10,6 @@ version = '1.0.0'
sourceCompatibility = 1.6
targetCompatibility = 1.6
//compileJava.options.bootClasspath = "C:/Program Files/Java/jre6/lib/rt.jar"
compileTestJava {
}
processTestResources {
}
testClasses {
}
test {
}
jar {
manifest {
@ -28,6 +20,19 @@ jar {
}
}
task testJar(type: Jar) {
classifier = 'test'
from sourceSets.test.output, sourceSets.main.output
manifest {
attributes 'Main-Class': 'com.fazecast.jSerialComm.SerialPortTest',
'Implementation-Title': 'jSerialComm: Java Serial Communications Library',
'Implementation-Version': version,
'Implementation-Vendor': 'Fazecast, Inc.',
'Sealed': 'true'
}
}
task javadocJar(type: Jar) {
classifier = 'javadoc'
from javadoc
@ -39,7 +44,7 @@ task sourcesJar(type: Jar) {
}
artifacts {
archives jar, javadocJar, sourcesJar
archives jar, javadocJar, sourcesJar, testJar
}
signing {

View File

@ -7,6 +7,7 @@ INCLUDES := -I"$(JDK_HOME)/include" -I"$(JDK_HOME)/include/linux"
LIBRARIES :=
DELETE := @rm
MKDIR := @mkdir
COPY := @cp
MOVE := @mv
PRINT := @echo
FULL_CLASS := com.fazecast.jSerialComm.SerialPort
@ -16,7 +17,8 @@ JFLAGS := -source 1.6 -target 1.6 -Xlint:-options
LIBRARY_NAME := libjSerialComm.so
SOURCES := SerialPort_Linux.cpp
JAVA_SOURCE_DIR = ../../../../src/main/java/com/fazecast/jSerialComm
RESOURCE_DIR = ../../../../src/main/resources/Linux
RESOURCE_DIR1 = ../../../../src/main/resources/Linux
RESOURCE_DIR2 = ../../../../src/test/resources/Linux
BUILD_DIR = ../../../../bin/Linux
JAVA_CLASS_DIR = $(BUILD_DIR)/../com/fazecast/jSerialComm
OBJECTSx86 = $(BUILD_DIR)/x86/$(SOURCES:.cpp=.o)
@ -38,13 +40,15 @@ all : linux32 linux64
linux32 : ARCH = -m32
linux32 : checkdirs $(BUILD_DIR)/x86/$(LIBRARY_NAME)
$(DELETE) -rf $(BUILD_DIR)/x86/*.o
$(MOVE) $(BUILD_DIR)/x86/*.* $(RESOURCE_DIR)/x86
$(COPY) $(BUILD_DIR)/x86/*.* $(RESOURCE_DIR1)/x86
$(MOVE) $(BUILD_DIR)/x86/*.* $(RESOURCE_DIR2)/x86
# Builds 64-bit Linux libraries
linux64 : ARCH = -m64
linux64 : checkdirs $(BUILD_DIR)/x86_64/$(LIBRARY_NAME)
$(DELETE) -rf $(BUILD_DIR)/x86_64/*.o
$(MOVE) $(BUILD_DIR)/x86_64/*.* $(RESOURCE_DIR)/x86_64
$(COPY) $(BUILD_DIR)/x86_64/*.* $(RESOURCE_DIR1)/x86_64
$(MOVE) $(BUILD_DIR)/x86_64/*.* $(RESOURCE_DIR2)/x86_64
# Rule to create build directories
checkdirs : $(BUILD_DIR)/x86 $(BUILD_DIR)/x86_64 $(JAVA_CLASS_DIR)

View File

@ -85,7 +85,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP
return arrayObject;
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPort(JNIEnv *env, jobject obj)
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(JNIEnv *env, jobject obj)
{
int fdSerial;
jstring portNameJString = (jstring)env->GetObjectField(obj, env->GetFieldID(env->GetObjectClass(obj), "comPort", "Ljava/lang/String;"));
@ -238,7 +238,7 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
return (tcsetattr(serialFD, TCSAFLUSH, &options) == 0) ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePort(JNIEnv *env, jobject obj)
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNative(JNIEnv *env, jobject obj)
{
// Close port
int portFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
@ -252,22 +252,25 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePort(JN
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAvailable(JNIEnv *env, jobject obj)
{
int serialPortFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
int numBytesAvailable;
int numBytesAvailable = -1;
if (serialPortFD != -1)
ioctl(serialPortFD, FIONREAD, &numBytesAvailable);
ioctl(serialPortFD, FIONREAD, &numBytesAvailable);
return numBytesAvailable;
}
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv *env, jobject obj, jbyteArray buffer, jlong bytesToRead)
{
// Get port handle and read timeout from Java class
char* readBuffer = (char*)malloc(bytesToRead);
jclass serialCommClass = env->GetObjectClass(obj);
int timeoutMode = env->GetIntField(obj, env->GetFieldID(serialCommClass, "timeoutMode", "I"));
int readTimeout = env->GetIntField(obj, env->GetFieldID(serialCommClass, "readTimeout", "I"));
int serialPortFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
if (serialPortFD == -1)
return -1;
int numBytesRead, numBytesReadTotal = 0, bytesRemaining = bytesToRead;
char* readBuffer = (char*)malloc(bytesToRead);
// Infinite blocking mode specified, don't return until we have completely finished the read
if (((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_READ_BLOCKING) > 0) && (readTimeout == 0))
@ -279,7 +282,6 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
{
// Problem reading, close port
close(serialPortFD);
serialPortFD = -1;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), -1l);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
break;
@ -309,7 +311,6 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
{
// Problem reading, close port
close(serialPortFD);
serialPortFD = -1;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), -1l);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
break;
@ -331,7 +332,6 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
{
// Problem reading, close port
close(serialPortFD);
serialPortFD = -1;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), -1l);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
}
@ -347,8 +347,10 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEnv *env, jobject obj, jbyteArray buffer, jlong bytesToWrite)
{
jbyte *writeBuffer = env->GetByteArrayElements(buffer, 0);
int serialPortFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
if (serialPortFD == -1)
return -1;
jbyte *writeBuffer = env->GetByteArrayElements(buffer, 0);
int numBytesWritten;
// Write to port
@ -356,7 +358,6 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
{
// Problem writing, close port
close(serialPortFD);
serialPortFD = -1;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), -1l);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
}

View File

@ -7,6 +7,7 @@ INCLUDES := -I"/System/Library/Frameworks/JavaVM.framework/Versions/Current/Hea
LIBRARIES := -framework Cocoa -framework IOKit -framework JavaVM
DELETE := @rm
MKDIR := @mkdir
COPY := @cp
MOVE := @mv
PRINT := @echo
FULL_CLASS := com.fazecast.jSerialComm.SerialPort
@ -16,7 +17,8 @@ JFLAGS := -source 1.6 -target 1.6 -Xlint:-options
LIBRARY_NAME := libjSerialComm.jnilib
SOURCES := SerialPort_OSX.cpp
JAVA_SOURCE_DIR = ../../../../src/main/java/com/fazecast/jSerialComm
RESOURCE_DIR = ../../../../src/main/resources/OSX
RESOURCE_DIR1 = ../../../../src/main/resources/OSX
RESOURCE_DIR2 = ../../../../src/test/resources/OSX
BUILD_DIR = ../../../../bin/OSX
JAVA_CLASS_DIR = $(BUILD_DIR)/../com/fazecast/jSerialComm
OBJECTSx86 = $(BUILD_DIR)/x86/$(SOURCES:.cpp=.o)
@ -38,13 +40,15 @@ all : osx32 osx64
osx32 : ARCH = -m32
osx32 : checkdirs $(BUILD_DIR)/x86/$(LIBRARY_NAME)
$(DELETE) -rf $(BUILD_DIR)/x86/*.o
$(MOVE) $(BUILD_DIR)/x86/*.* $(RESOURCE_DIR)/x86
$(COPY) $(BUILD_DIR)/x86/*.* $(RESOURCE_DIR1)/x86
$(MOVE) $(BUILD_DIR)/x86/*.* $(RESOURCE_DIR2)/x86
# Builds 64-bit OSX libraries
osx64 : ARCH = -m64
osx64 : checkdirs $(BUILD_DIR)/x86_64/$(LIBRARY_NAME)
$(DELETE) -rf $(BUILD_DIR)/x86_64/*.o
$(MOVE) $(BUILD_DIR)/x86_64/*.* $(RESOURCE_DIR)/x86_64
$(COPY) $(BUILD_DIR)/x86_64/*.* $(RESOURCE_DIR1)/x86_64
$(MOVE) $(BUILD_DIR)/x86_64/*.* $(RESOURCE_DIR2)/x86_64
# Rule to create build directories
checkdirs : $(BUILD_DIR)/x86 $(BUILD_DIR)/x86_64 $(JAVA_CLASS_DIR)

View File

@ -81,7 +81,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP
return arrayObject;
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPort(JNIEnv *env, jobject obj)
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(JNIEnv *env, jobject obj)
{
int fdSerial;
jstring portNameJString = (jstring)env->GetObjectField(obj, env->GetFieldID(env->GetObjectClass(obj), "comPort", "Ljava/lang/String;"));
@ -224,7 +224,7 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
return (tcsetattr(serialFD, TCSAFLUSH, &options) == 0) ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePort(JNIEnv *env, jobject obj)
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNative(JNIEnv *env, jobject obj)
{
// Close port
int portFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
@ -238,22 +238,25 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePort(JN
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAvailable(JNIEnv *env, jobject obj)
{
int serialPortFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
int numBytesAvailable;
int numBytesAvailable = -1;
if (serialPortFD != -1)
ioctl(serialPortFD, FIONREAD, &numBytesAvailable);
ioctl(serialPortFD, FIONREAD, &numBytesAvailable);
return numBytesAvailable;
}
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv *env, jobject obj, jbyteArray buffer, jlong bytesToRead)
{
// Get port handle and read timeout from Java class
char* readBuffer = (char*)malloc(bytesToRead);
jclass serialCommClass = env->GetObjectClass(obj);
int timeoutMode = env->GetIntField(obj, env->GetFieldID(serialCommClass, "timeoutMode", "I"));
int readTimeout = env->GetIntField(obj, env->GetFieldID(serialCommClass, "readTimeout", "I"));
int serialPortFD = (int)env->GetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"));
if (serialPortFD == -1)
return -1;
int numBytesRead, numBytesReadTotal = 0, bytesRemaining = bytesToRead;
char* readBuffer = (char*)malloc(bytesToRead);
// Infinite blocking mode specified, don't return until we have completely finished the read
if (((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_READ_BLOCKING) > 0) && (readTimeout == 0))
@ -265,7 +268,6 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
{
// Problem reading, close port
close(serialPortFD);
serialPortFD = -1;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), -1l);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
break;
@ -295,7 +297,6 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
{
// Problem reading, close port
close(serialPortFD);
serialPortFD = -1;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), -1l);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
break;
@ -317,7 +318,6 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
{
// Problem reading, close port
close(serialPortFD);
serialPortFD = -1;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), -1l);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
}
@ -333,8 +333,10 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEnv *env, jobject obj, jbyteArray buffer, jlong bytesToWrite)
{
jbyte *writeBuffer = env->GetByteArrayElements(buffer, 0);
int serialPortFD = (int)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
if (serialPortFD == -1)
return -1;
jbyte *writeBuffer = env->GetByteArrayElements(buffer, 0);
int numBytesWritten;
// Write to port
@ -342,7 +344,6 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
{
// Problem writing, close port
close(serialPortFD);
serialPortFD = -1;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), -1l);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
}

View File

@ -8,6 +8,7 @@ LIBRARIES = Advapi32.lib
DELETE = @del /q /f
RMDIR = @rmdir /q /s
MKDIR = @mkdir
COPY = @copy /y
MOVE = @move /y
PRINT = @echo
FULL_CLASS = com.fazecast.jSerialComm.SerialPort
@ -17,7 +18,8 @@ JFLAGS = -source 1.6 -target 1.6 -Xlint:-options
LIBRARY_NAME = jSerialComm.dll
SOURCES = SerialPort_Windows.cpp
JAVA_SOURCE_DIR = ../../../../src/main/java/com/fazecast/jSerialComm
RESOURCE_DIR = ../../../../src/main/resources/Windows
RESOURCE_DIR1 = ../../../../src/main/resources/Windows
RESOURCE_DIR2 = ../../../../src/test/resources/Windows
BUILD_DIR = ../../../../bin/Windows
JAVA_CLASS_DIR = $(BUILD_DIR)/../com/fazecast/jSerialComm
OBJECTSx86 = $(BUILD_DIR)/x86/$(SOURCES:.cpp=.o)
@ -39,20 +41,22 @@ all :
$(PRINT).
$(PRINT) Example: To build 64-bit Windows libraries, you would call:
$(PRINT) C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/vcvarsall.bat x64
$(PRINT) make (or mingw32-make)
$(PRINT) mingw32-make
$(PRINT).
# Builds 32-bit Windows libraries
win32 : checkdirs $(BUILD_DIR)/x86/$(LIBRARY_NAME)
$(DELETE) "$(BUILD_DIR)"\\x86\\*.o
$(MOVE) "$(BUILD_DIR)"\\x86\\*.* "$(RESOURCE_DIR)"\\x86
$(COPY) "$(BUILD_DIR)"\\x86\\*.* "$(RESOURCE_DIR1)"\\x86
$(MOVE) "$(BUILD_DIR)"\\x86\\*.* "$(RESOURCE_DIR2)"\\x86
$(DELETE) ".."\\*.h
$(RMDIR) "$(BUILD_DIR)/.."
# Builds 64-bit Windows libraries
win64 : checkdirs $(BUILD_DIR)/x86_64/$(LIBRARY_NAME)
$(DELETE) "$(BUILD_DIR)"\\x86_64\\*.o
$(MOVE) "$(BUILD_DIR)"\\x86_64\\*.* "$(RESOURCE_DIR)"\\x86_64
$(COPY) "$(BUILD_DIR)"\\x86_64\\*.* "$(RESOURCE_DIR1)"\\x86_64
$(MOVE) "$(BUILD_DIR)"\\x86_64\\*.* "$(RESOURCE_DIR2)"\\x86_64
$(DELETE) ".."\\*.h
$(RMDIR) "$(BUILD_DIR)/.."

View File

@ -187,7 +187,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP
return arrayObject;
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPort(JNIEnv *env, jobject obj)
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(JNIEnv *env, jobject obj)
{
jclass serialCommClass = env->GetObjectClass(obj);
jstring portNameJString = (jstring)env->GetObjectField(obj, env->GetFieldID(serialCommClass, "comPort", "Ljava/lang/String;"));
@ -195,7 +195,7 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPort(JNI
const char *portName = env->GetStringUTFChars(portNameJString, NULL);
// Try to open existing serial port with read/write access
if ((serialPortHandle = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)) != INVALID_HANDLE_VALUE)
if ((serialPortHandle = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED, NULL)) != INVALID_HANDLE_VALUE)
{
// Set port handle in Java structure
env->SetLongField(obj, env->GetFieldID(serialCommClass, "portHandle", "J"), (jlong)serialPortHandle);
@ -357,7 +357,7 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeou
return SetCommTimeouts(serialHandle, &timeouts);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePort(JNIEnv *env, jobject obj)
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNative(JNIEnv *env, jobject obj)
{
// Purge any outstanding port operations
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
@ -375,9 +375,11 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePort(JN
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAvailable(JNIEnv *env, jobject obj)
{
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
if (serialPortHandle == INVALID_HANDLE_VALUE)
return -1;
COMSTAT commInfo;
DWORD numBytesAvailable;
if (!ClearCommError(serialPortHandle, NULL, &commInfo))
return -1;
numBytesAvailable = commInfo.cbInQue;
@ -388,45 +390,38 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAvailable(J
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv *env, jobject obj, jbyteArray buffer, jlong bytesToRead)
{
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
OVERLAPPED overlappedStruct = {0};
overlappedStruct.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (serialPortHandle == INVALID_HANDLE_VALUE)
return -1;
OVERLAPPED overlappedStruct = {0};
overlappedStruct.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (overlappedStruct.hEvent == NULL)
{
CloseHandle(overlappedStruct.hEvent);
return -1;
}
char *readBuffer = (char*)malloc(bytesToRead);
DWORD numBytesRead = 0;
BOOL result;
// Read from serial port
if ((result = ReadFile(serialPortHandle, readBuffer, bytesToRead, NULL, &overlappedStruct)) != FALSE) // Immediately successful
GetOverlappedResult(serialPortHandle, &overlappedStruct, &numBytesRead, TRUE);
else if (GetLastError() != ERROR_IO_PENDING) // Problem occurred
if ((result = ReadFile(serialPortHandle, readBuffer, bytesToRead, &numBytesRead, &overlappedStruct)) == FALSE)
{
// Problem reading, close port
CloseHandle(serialPortHandle);
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), (jlong)INVALID_HANDLE_VALUE);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
}
else // Pending read operation
{
switch (WaitForSingleObject(overlappedStruct.hEvent, INFINITE))
{
case WAIT_OBJECT_0:
if ((result = GetOverlappedResult(serialPortHandle, &overlappedStruct, &numBytesRead, TRUE)) == FALSE)
{
// Problem reading, close port
CloseHandle(serialPortHandle);
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), (jlong)INVALID_HANDLE_VALUE);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
}
break;
default:
// Problem reading, close port
CloseHandle(serialPortHandle);
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), (jlong)INVALID_HANDLE_VALUE);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
break;
}
if (GetLastError() != ERROR_IO_PENDING) // Problem occurred
{
// Problem reading, close port
CloseHandle(serialPortHandle);
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), (jlong)INVALID_HANDLE_VALUE);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
}
else if ((result = GetOverlappedResult(serialPortHandle, &overlappedStruct, &numBytesRead, TRUE)) == FALSE)
{
// Problem reading, close port
CloseHandle(serialPortHandle);
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), (jlong)INVALID_HANDLE_VALUE);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
}
}
// Return number of bytes read if successful
@ -439,14 +434,21 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEnv *env, jobject obj, jbyteArray buffer, jlong bytesToWrite)
{
HANDLE serialPortHandle = (HANDLE)env->GetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"));
if (serialPortHandle == INVALID_HANDLE_VALUE)
return -1;
OVERLAPPED overlappedStruct = {0};
overlappedStruct.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
overlappedStruct.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (overlappedStruct.hEvent == NULL)
{
CloseHandle(overlappedStruct.hEvent);
return -1;
}
jbyte *writeBuffer = env->GetByteArrayElements(buffer, 0);
DWORD numBytesWritten = 0;
BOOL result;
// Write to port
if ((result = WriteFile(serialPortHandle, writeBuffer, bytesToWrite, NULL, &overlappedStruct)) == FALSE)
// Write to serial port
if ((result = WriteFile(serialPortHandle, writeBuffer, bytesToWrite, &numBytesWritten, &overlappedStruct)) == FALSE)
{
if (GetLastError() != ERROR_IO_PENDING)
{
@ -456,32 +458,15 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), (jlong)INVALID_HANDLE_VALUE);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
}
else
else if ((result = GetOverlappedResult(serialPortHandle, &overlappedStruct, &numBytesWritten, TRUE)) == FALSE)
{
switch (WaitForSingleObject(overlappedStruct.hEvent, INFINITE))
{
case WAIT_OBJECT_0:
if ((result = GetOverlappedResult(serialPortHandle, &overlappedStruct, &numBytesWritten, TRUE)) == FALSE)
{
// Problem reading, close port
CloseHandle(serialPortHandle);
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), (jlong)INVALID_HANDLE_VALUE);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
}
break;
default:
// Problem reading, close port
CloseHandle(serialPortHandle);
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), (jlong)INVALID_HANDLE_VALUE);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
break;
}
// Problem reading, close port
CloseHandle(serialPortHandle);
serialPortHandle = INVALID_HANDLE_VALUE;
env->SetLongField(obj, env->GetFieldID(env->GetObjectClass(obj), "portHandle", "J"), (jlong)INVALID_HANDLE_VALUE);
env->SetBooleanField(obj, env->GetFieldID(env->GetObjectClass(obj), "isOpened", "Z"), JNI_FALSE);
}
}
else
GetOverlappedResult(serialPortHandle, &overlappedStruct, &numBytesWritten, TRUE);
// Return number of bytes written if successful
CloseHandle(overlappedStruct.hEvent);

View File

@ -161,16 +161,35 @@ public class SerialPort
*
* @return Whether the port was successfully opened.
*/
public final native boolean openPort();
public final boolean openPort()
{
try { Thread.sleep(500); } catch (Exception e) {}
if (!isOpened && openPortNative())
{
inputStream = new SerialPortInputStream();
outputStream = new SerialPortOutputStream();
}
return isOpened;
}
/**
* Closes this serial port.
*
* @return Whether the port was successfully closed.
*/
public final native boolean closePort();
public final boolean closePort()
{
if (isOpened && closePortNative())
{
inputStream = null;
outputStream = null;
}
return !isOpened;
}
// Serial Port Setup Methods
private final native boolean openPortNative();
private final native boolean closePortNative();
private final native boolean configPort(); // Changes/sets serial port parameters as defined by this class
private final native boolean configFlowControl(); // Changes/sets flow control parameters as defined by this class
private final native boolean configTimeouts(); // Changes/sets serial port timeouts as defined by this class
@ -179,7 +198,7 @@ public class SerialPort
* Returns the number of bytes available without blocking if {@link #readBytes} were to be called immediately
* after this method returns.
*
* @return The number of bytes currently available to be read.
* @return The number of bytes currently available to be read, or -1 if the port is not open.
*/
public final native int bytesAvailable();
@ -226,12 +245,7 @@ public class SerialPort
* @return An {@link java.io.InputStream} object associated with this serial port.
* @see java.io.InputStream
*/
public final InputStream getInputStream()
{
if ((inputStream == null) && isOpened)
inputStream = new SerialPortInputStream();
return inputStream;
}
public final InputStream getInputStream() { return inputStream; }
/**
* Returns an {@link java.io.OutputStream} object associated with this serial port.
@ -243,12 +257,7 @@ public class SerialPort
* @return An {@link java.io.OutputStream} object associated with this serial port.
* @see java.io.OutputStream
*/
public final OutputStream getOutputStream()
{
if ((outputStream == null) && isOpened)
outputStream = new SerialPortOutputStream();
return outputStream;
}
public final OutputStream getOutputStream() { return outputStream; }
/**
* Sets all serial port parameters at one time.
@ -279,11 +288,15 @@ public class SerialPort
*/
public final void setComPortParameters(int newBaudRate, int newDataBits, int newStopBits, int newParity)
{
baudRate = newBaudRate;
dataBits = newDataBits;
stopBits = newStopBits;
parity = newParity;
configPort();
if (isOpened)
{
try { Thread.sleep(200); } catch (Exception e) {}
baudRate = newBaudRate;
dataBits = newDataBits;
stopBits = newStopBits;
parity = newParity;
configPort();
}
}
/**
@ -310,7 +323,7 @@ public class SerialPort
* <i>newReadTimeout</i> or <i>newWriteTimeout</i> milliseconds of inactivity have elapsed or at least 1 byte of data can be written or read.
* <p>
* The {@link #TIMEOUT_READ_BLOCKING} or {@link #TIMEOUT_WRITE_BLOCKING} modes specify that the corresponding call will block until either
* <i>newReadTimeout</i> or <i>newWriteTimeout</i> milliseconds of inactivity have elapsed or the total number of requested bytes can be written or
* <i>newReadTimeout</i> or <i>newWriteTimeout</i> milliseconds have elapsed since the start of the call or the total number of requested bytes can be written or
* returned.
* <p>
* A value of 0 for either <i>newReadTimeout</i> or <i>newWriteTimeout</i> indicates that a {@link #readBytes(byte[],long)} or
@ -322,10 +335,14 @@ public class SerialPort
*/
public final void setComPortTimeouts(int newTimeoutMode, int newReadTimeout, int newWriteTimeout)
{
timeoutMode = newTimeoutMode;
readTimeout = newReadTimeout;
writeTimeout = newWriteTimeout;
configTimeouts();
if (isOpened)
{
try { Thread.sleep(200); } catch (Exception e) {}
timeoutMode = newTimeoutMode;
readTimeout = newReadTimeout;
writeTimeout = newWriteTimeout;
configTimeouts();
}
}
/**
@ -335,7 +352,15 @@ public class SerialPort
*
* @param newBaudRate The desired baud rate for this serial port.
*/
public final void setBaudRate(int newBaudRate) { baudRate = newBaudRate; configPort(); }
public final void setBaudRate(int newBaudRate)
{
if (isOpened)
{
try { Thread.sleep(200); } catch (Exception e) {}
baudRate = newBaudRate;
configPort();
}
}
/**
* Sets the desired number of data bits per word.
@ -344,7 +369,15 @@ public class SerialPort
*
* @param newDataBits The desired number of data bits per word.
*/
public final void setNumDataBits(int newDataBits) { dataBits = newDataBits; configPort(); }
public final void setNumDataBits(int newDataBits)
{
if (isOpened)
{
try { Thread.sleep(200); } catch (Exception e) {}
dataBits = newDataBits;
configPort();
}
}
/**
* Sets the desired number of stop bits per word.
@ -359,7 +392,15 @@ public class SerialPort
* @see #ONE_POINT_FIVE_STOP_BITS
* @see #TWO_STOP_BITS
*/
public final void setNumStopBits(int newStopBits) { stopBits = newStopBits; configPort(); }
public final void setNumStopBits(int newStopBits)
{
if (isOpened)
{
try { Thread.sleep(200); } catch (Exception e) {}
stopBits = newStopBits;
configPort();
}
}
/**
* Specifies what kind of flow control to enable for this serial port.
@ -389,7 +430,15 @@ public class SerialPort
* @see #FLOW_CONTROL_XONXOFF_IN_ENABLED
* @see #FLOW_CONTROL_XONXOFF_OUT_ENABLED
*/
public final void setFlowControl(int newFlowControlSettings) { flowControl = newFlowControlSettings; configFlowControl(); }
public final void setFlowControl(int newFlowControlSettings)
{
if (isOpened)
{
try { Thread.sleep(200); } catch (Exception e) {}
flowControl = newFlowControlSettings;
configFlowControl();
}
}
/**
* Sets the desired parity error-detection scheme to be used.
@ -404,7 +453,15 @@ public class SerialPort
* @see #MARK_PARITY
* @see #SPACE_PARITY
*/
public final void setParity(int newParity) { parity = newParity; configPort(); }
public final void setParity(int newParity)
{
if (isOpened)
{
try { Thread.sleep(200); } catch (Exception e) {}
parity = newParity;
configPort();
}
}
/**
* Gets a descriptive string representing this serial port or the device connected to it.
@ -619,99 +676,4 @@ public class SerialPort
throw new IOException("This port appears to have been shutdown or disconnected.");
}
}
static public void main(String[] args)
{
SerialPort[] ports = SerialPort.getCommPorts();
System.out.println("\nPorts:\n");
for (int i = 0; i < ports.length; ++i)
System.out.println(" " + ports[i].getSystemPortName() + ": " + ports[i].getDescriptivePortName());
SerialPort ubxPort = ports[1];
byte[] readBuffer = new byte[2048];
System.out.println("\nOpening " + ubxPort.getDescriptivePortName() + ": " + ubxPort.openPort());
System.out.println("Setting read timeout mode to non-blocking");
ubxPort.setComPortTimeouts(TIMEOUT_NONBLOCKING, 1000, 0);
InputStream in = ubxPort.getInputStream();
try
{
for (int i = 0; i < 3; ++i)
{
System.out.println("\nReading #" + i);
System.out.println("Available: " + ubxPort.bytesAvailable());
int numRead = ubxPort.readBytes(readBuffer, readBuffer.length);
System.out.println("Read " + numRead + " bytes.");
}
in.close();
} catch (Exception e) { e.printStackTrace(); }
System.out.println("\nSetting read timeout mode to semi-blocking with a timeout of 200ms");
ubxPort.setComPortTimeouts(TIMEOUT_READ_SEMI_BLOCKING, 200, 0);
in = ubxPort.getInputStream();
try
{
for (int i = 0; i < 3; ++i)
{
System.out.println("\nReading #" + i);
System.out.println("Available: " + ubxPort.bytesAvailable());
int numRead = ubxPort.readBytes(readBuffer, readBuffer.length);
System.out.println("Read " + numRead + " bytes.");
}
in.close();
} catch (Exception e) { e.printStackTrace(); }
System.out.println("\nSetting read timeout mode to semi-blocking with no timeout");
ubxPort.setComPortTimeouts(TIMEOUT_READ_SEMI_BLOCKING, 0, 0);
in = ubxPort.getInputStream();
try
{
for (int i = 0; i < 3; ++i)
{
System.out.println("\nReading #" + i);
System.out.println("Available: " + ubxPort.bytesAvailable());
int numRead = ubxPort.readBytes(readBuffer, readBuffer.length);
System.out.println("Read " + numRead + " bytes.");
}
in.close();
} catch (Exception e) { e.printStackTrace(); }
System.out.println("\nSetting read timeout mode to blocking with a timeout of 100ms");
ubxPort.setComPortTimeouts(TIMEOUT_READ_BLOCKING, 100, 0);
in = ubxPort.getInputStream();
try
{
for (int i = 0; i < 3; ++i)
{
System.out.println("\nReading #" + i);
System.out.println("Available: " + ubxPort.bytesAvailable());
int numRead = ubxPort.readBytes(readBuffer, readBuffer.length);
System.out.println("Read " + numRead + " bytes.");
}
in.close();
} catch (Exception e) { e.printStackTrace(); }
System.out.println("\nSetting read timeout mode to blocking with no timeout");
ubxPort.setComPortTimeouts(TIMEOUT_READ_BLOCKING, 0, 0);
in = ubxPort.getInputStream();
try
{
for (int i = 0; i < 3; ++i)
{
System.out.println("\nReading #" + i);
System.out.println("Available: " + ubxPort.bytesAvailable());
int numRead = ubxPort.readBytes(readBuffer, readBuffer.length);
System.out.println("Read " + numRead + " bytes.");
}
in.close();
} catch (Exception e) { e.printStackTrace(); }
System.out.println("\n\nClosing " + ubxPort.getDescriptivePortName() + ": " + ubxPort.closePort());
try { Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace(); }
System.out.println("Reopening " + ubxPort.getDescriptivePortName() + ": " + ubxPort.openPort() + "\n");
ubxPort.setComPortTimeouts(TIMEOUT_READ_BLOCKING, 1000, 0);
in = ubxPort.getInputStream();
try
{
for (int j = 0; j < 1000; ++j)
System.out.print((char)in.read());
in.close();
} catch (Exception e) { e.printStackTrace(); }
System.out.println("\nClosing " + ubxPort.getDescriptivePortName() + ": " + ubxPort.closePort());
}
}

View File

@ -0,0 +1,124 @@
/*
* SerialPortTest.java
*
* Created on: Feb 27, 2015
* Last Updated on: Feb 27, 2015
* Author: Will Hedgecock
*
* Copyright (C) 2012-2015 Fazecast, Inc.
*
* This file is part of jSerialComm.
*
* jSerialComm is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jSerialComm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with jSerialComm. If not, see <http://www.gnu.org/licenses/>.
*/
package com.fazecast.jSerialComm;
import java.io.InputStream;
/**
* This class provides a test case for the jSerialComm library.
*
* @author Will Hedgecock &lt;will.hedgecock@gmail.com&gt;
* @version 1.0
* @see java.io.InputStream
* @see java.io.OutputStream
*/
public class SerialPortTest
{
static public void main(String[] args)
{
SerialPort[] ports = SerialPort.getCommPorts();
System.out.println("\nPorts:\n");
for (int i = 0; i < ports.length; ++i)
System.out.println(" " + ports[i].getSystemPortName() + ": " + ports[i].getDescriptivePortName());
SerialPort ubxPort = ports[1];
byte[] readBuffer = new byte[2048];
System.out.println("\nOpening " + ubxPort.getDescriptivePortName() + ": " + ubxPort.openPort());
System.out.println("Setting read timeout mode to non-blocking");
ubxPort.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 1000, 0);
try
{
for (int i = 0; i < 3; ++i)
{
System.out.println("\nReading #" + i);
System.out.println("Available: " + ubxPort.bytesAvailable());
int numRead = ubxPort.readBytes(readBuffer, readBuffer.length);
System.out.println("Read " + numRead + " bytes.");
}
} catch (Exception e) { e.printStackTrace(); }
System.out.println("\nSetting read timeout mode to semi-blocking with a timeout of 200ms");
ubxPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 200, 0);
try
{
for (int i = 0; i < 3; ++i)
{
System.out.println("\nReading #" + i);
System.out.println("Available: " + ubxPort.bytesAvailable());
int numRead = ubxPort.readBytes(readBuffer, readBuffer.length);
System.out.println("Read " + numRead + " bytes.");
}
} catch (Exception e) { e.printStackTrace(); }
System.out.println("\nSetting read timeout mode to semi-blocking with no timeout");
ubxPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0);
try
{
for (int i = 0; i < 3; ++i)
{
System.out.println("\nReading #" + i);
System.out.println("Available: " + ubxPort.bytesAvailable());
int numRead = ubxPort.readBytes(readBuffer, readBuffer.length);
System.out.println("Read " + numRead + " bytes.");
}
} catch (Exception e) { e.printStackTrace(); }
System.out.println("\nSetting read timeout mode to blocking with a timeout of 100ms");
ubxPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING, 100, 0);
try
{
for (int i = 0; i < 3; ++i)
{
System.out.println("\nReading #" + i);
System.out.println("Available: " + ubxPort.bytesAvailable());
int numRead = ubxPort.readBytes(readBuffer, readBuffer.length);
System.out.println("Read " + numRead + " bytes.");
}
} catch (Exception e) { e.printStackTrace(); }
System.out.println("\nSetting read timeout mode to blocking with no timeout");
ubxPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING, 0, 0);
try
{
for (int i = 0; i < 3; ++i)
{
System.out.println("\nReading #" + i);
System.out.println("Available: " + ubxPort.bytesAvailable());
int numRead = ubxPort.readBytes(readBuffer, readBuffer.length);
System.out.println("Read " + numRead + " bytes.");
}
} catch (Exception e) { e.printStackTrace(); }
System.out.println("\n\nClosing " + ubxPort.getDescriptivePortName() + ": " + ubxPort.closePort());
try { Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace(); }
System.out.println("Reopening " + ubxPort.getDescriptivePortName() + ": " + ubxPort.openPort() + "\n");
ubxPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING, 1000, 0);
InputStream in = ubxPort.getInputStream();
try
{
for (int j = 0; j < 1000; ++j)
System.out.print((char)in.read());
in.close();
} catch (Exception e) { e.printStackTrace(); }
System.out.println("\n\nClosing " + ubxPort.getDescriptivePortName() + ": " + ubxPort.closePort());
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.