Set/clear RTS/DTR prior to opening, disable port configuration, allow user to specify driver input/output queue size, remove built-in dependency on FTDI

This commit is contained in:
hedgecrw85 2018-10-08 09:47:59 -05:00
parent e9bf1527ad
commit 7adf2f6a3a
34 changed files with 463 additions and 159 deletions

View File

@ -2,7 +2,7 @@
* SerialPort_Android.c
*
* Created on: Mar 13, 2015
* Last Updated on: Jul 27, 2018
* Last Updated on: Oct 07, 2018
* Author: Will Hedgecock
*
* Copyright (C) 2012-2018 Fazecast, Inc.
@ -54,6 +54,9 @@ jfieldID comPortField;
jfieldID friendlyNameField;
jfieldID portDescriptionField;
jfieldID isOpenedField;
jfieldID disableConfigField;
jfieldID isDtrEnabledField;
jfieldID isRtsEnabledField;
jfieldID baudRateField;
jfieldID dataBitsField;
jfieldID stopBitsField;
@ -104,6 +107,9 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
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");
disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z");
isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z");
isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z");
baudRateField = (*env)->GetFieldID(env, serialCommClass, "baudRate", "I");
dataBitsField = (*env)->GetFieldID(env, serialCommClass, "dataBits", "I");
stopBitsField = (*env)->GetFieldID(env, serialCommClass, "stopBits", "I");
@ -126,6 +132,8 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
// TODO: SET A FLAG SAYING THAT WE ARE NOT USING USBFS
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
unsigned char isDtrEnabled = (*env)->GetBooleanField(env, obj, isDtrEnabledField);
unsigned char isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField);
// Try to open existing serial port with read/write access
int serialPortFD = -1;
@ -138,6 +146,9 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
fcntl(serialPortFD, F_SETFL, 0);
ioctl(serialPortFD, TCGETS, &options);
cfmakeraw(&options);
if (!isDtrEnabled || !isRtsEnabled)
options.c_cflag &= ~HUPCL;
options.c_iflag |= BRKINT;
ioctl(serialPortFD, TCSETS, &options);
}
@ -192,6 +203,9 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
int stopBitsInt = (*env)->GetIntField(env, obj, stopBitsField);
int parityInt = (*env)->GetIntField(env, obj, parityField);
int flowControl = (*env)->GetIntField(env, obj, flowControlField);
unsigned char configDisabled = (*env)->GetBooleanField(env, obj, disableConfigField);
unsigned char isDtrEnabled = (*env)->GetBooleanField(env, obj, isDtrEnabledField);
unsigned char isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField);
tcflag_t byteSize = (byteSizeInt == 5) ? CS5 : (byteSizeInt == 6) ? CS6 : (byteSizeInt == 7) ? CS7 : CS8;
tcflag_t stopBits = ((stopBitsInt == com_fazecast_jSerialComm_SerialPort_ONE_STOP_BIT) || (stopBitsInt == com_fazecast_jSerialComm_SerialPort_ONE_POINT_FIVE_STOP_BITS)) ? 0 : CSTOPB;
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);
@ -207,6 +221,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
options.c_cflag = (byteSize | stopBits | parity | CLOCAL | CREAD | CTSRTSEnabled);
if (parityInt == com_fazecast_jSerialComm_SerialPort_SPACE_PARITY)
options.c_cflag &= ~PARODD;
if (!isDtrEnabled || !isRtsEnabled)
options.c_cflag &= ~HUPCL;
options.c_iflag &= ~(INPCK | IGNPAR | PARMRK | ISTRIP);
if (byteSizeInt < 8)
options.c_iflag |= ISTRIP;
@ -235,7 +251,7 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
// Apply changes
int retVal = -1;
if (isatty(serialPortFD))
retVal = ioctl(serialPortFD, TCSETS, &options);
retVal = configDisabled ? 0 : ioctl(serialPortFD, TCSETS, &options);
else
return JNI_FALSE;/*
{
@ -577,6 +593,34 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearRTS(JNI
return (ioctl(serialPortFD, TIOCMBIC, &modemBits) == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_presetRTS(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
// Send a system command to preset the RTS mode of the serial port
char commandString[64];
sprintf(commandString, "stty -f %s hupcl", portName);
int result = system(commandString);
(*env)->ReleaseStringUTFChars(env, portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_preclearRTS(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
// Send a system command to preset the RTS mode of the serial port
char commandString[64];
sprintf(commandString, "stty -f %s -hupcl", portName);
int result = system(commandString);
(*env)->ReleaseStringUTFChars(env, portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_setDTR(JNIEnv *env, jobject obj, jlong serialPortFD)
{
if (serialPortFD <= 0)
@ -593,6 +637,34 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearDTR(JNI
return (ioctl(serialPortFD, TIOCMBIC, &modemBits) == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_presetDTR(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
// Send a system command to preset the DTR mode of the serial port
char commandString[64];
sprintf(commandString, "stty -f %s hupcl", portName);
int result = system(commandString);
(*env)->ReleaseStringUTFChars(env, portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_preclearDTR(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
// Send a system command to preset the DTR mode of the serial port
char commandString[64];
sprintf(commandString, "stty -f %s -hupcl", portName);
int result = system(commandString);
(*env)->ReleaseStringUTFChars(env, portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCTS(JNIEnv *env, jobject obj, jlong serialPortFD)
{
if (serialPortFD <= 0)

View File

@ -191,6 +191,22 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_setRTS
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearRTS
(JNIEnv *, jobject, jlong);
/*
* Class: com_fazecast_jSerialComm_SerialPort
* Method: presetRTS
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_presetRTS
(JNIEnv *, jobject);
/*
* Class: com_fazecast_jSerialComm_SerialPort
* Method: preclearRTS
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_preclearRTS
(JNIEnv *, jobject);
/*
* Class: com_fazecast_jSerialComm_SerialPort
* Method: setDTR
@ -207,6 +223,22 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_setDTR
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearDTR
(JNIEnv *, jobject, jlong);
/*
* Class: com_fazecast_jSerialComm_SerialPort
* Method: presetDTR
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_presetDTR
(JNIEnv *, jobject);
/*
* Class: com_fazecast_jSerialComm_SerialPort
* Method: preclearDTR
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_preclearDTR
(JNIEnv *, jobject);
/*
* Class: com_fazecast_jSerialComm_SerialPort
* Method: getCTS

View File

@ -2,7 +2,7 @@
* SerialPort_Linux.c
*
* Created on: Feb 25, 2012
* Last Updated on: Jul 27, 2018
* Last Updated on: Oct 07, 2018
* Author: Will Hedgecock
*
* Copyright (C) 2012-2018 Fazecast, Inc.
@ -47,6 +47,9 @@ jfieldID comPortField;
jfieldID friendlyNameField;
jfieldID portDescriptionField;
jfieldID isOpenedField;
jfieldID disableConfigField;
jfieldID isDtrEnabledField;
jfieldID isRtsEnabledField;
jfieldID baudRateField;
jfieldID dataBitsField;
jfieldID stopBitsField;
@ -98,6 +101,9 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
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");
disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z");
isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z");
isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z");
baudRateField = (*env)->GetFieldID(env, serialCommClass, "baudRate", "I");
dataBitsField = (*env)->GetFieldID(env, serialCommClass, "dataBits", "I");
stopBitsField = (*env)->GetFieldID(env, serialCommClass, "stopBits", "I");
@ -119,6 +125,8 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
unsigned char isDtrEnabled = (*env)->GetBooleanField(env, obj, isDtrEnabledField);
unsigned char isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField);
// Try to open existing serial port with read/write access
int serialPortFD = -1;
@ -129,6 +137,8 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
fcntl(serialPortFD, F_SETFL, 0);
tcgetattr(serialPortFD, &options);
cfmakeraw(&options);
if (!isDtrEnabled || !isRtsEnabled)
options.c_cflag &= ~HUPCL;
options.c_iflag |= BRKINT;
tcsetattr(serialPortFD, TCSANOW, &options);
@ -150,11 +160,6 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
return serialPortFD;
}
//JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_associateNativeHandle(JNIEnv *env, jobject obj, jlong serialPortFD)
//{
// ;
//}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(JNIEnv *env, jobject obj, jlong serialPortFD)
{
if (serialPortFD <= 0)
@ -167,6 +172,9 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
int stopBitsInt = (*env)->GetIntField(env, obj, stopBitsField);
int parityInt = (*env)->GetIntField(env, obj, parityField);
int flowControl = (*env)->GetIntField(env, obj, flowControlField);
unsigned char configDisabled = (*env)->GetBooleanField(env, obj, disableConfigField);
unsigned char isDtrEnabled = (*env)->GetBooleanField(env, obj, isDtrEnabledField);
unsigned char isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField);
tcflag_t byteSize = (byteSizeInt == 5) ? CS5 : (byteSizeInt == 6) ? CS6 : (byteSizeInt == 7) ? CS7 : CS8;
tcflag_t stopBits = ((stopBitsInt == com_fazecast_jSerialComm_SerialPort_ONE_STOP_BIT) || (stopBitsInt == com_fazecast_jSerialComm_SerialPort_ONE_POINT_FIVE_STOP_BITS)) ? 0 : CSTOPB;
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);
@ -180,6 +188,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
options.c_cflag = (byteSize | stopBits | parity | CLOCAL | CREAD | CTSRTSEnabled);
if (parityInt == com_fazecast_jSerialComm_SerialPort_SPACE_PARITY)
options.c_cflag &= ~PARODD;
if (!isDtrEnabled || !isRtsEnabled)
options.c_cflag &= ~HUPCL;
options.c_iflag &= ~(INPCK | IGNPAR | PARMRK | ISTRIP);
if (byteSizeInt < 8)
options.c_iflag |= ISTRIP;
@ -196,7 +206,7 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
}
// Apply changes
int retVal = tcsetattr(serialPortFD, TCSANOW, &options);
int retVal = configDisabled ? 0 : tcsetattr(serialPortFD, TCSANOW, &options);
ioctl(serialPortFD, TIOCEXCL); // Block non-root users from opening this port
if (baudRateCode == 0) // Set custom baud rate
setBaudRate(serialPortFD, baudRate);
@ -537,6 +547,34 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearRTS(JNI
return (ioctl(serialPortFD, TIOCMBIC, &modemBits) == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_presetRTS(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
// Send a system command to preset the RTS mode of the serial port
char commandString[64];
sprintf(commandString, "stty -f %s hupcl", portName);
int result = system(commandString);
(*env)->ReleaseStringUTFChars(env, portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_preclearRTS(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
// Send a system command to preset the RTS mode of the serial port
char commandString[64];
sprintf(commandString, "stty -f %s -hupcl", portName);
int result = system(commandString);
(*env)->ReleaseStringUTFChars(env, portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_setDTR(JNIEnv *env, jobject obj, jlong serialPortFD)
{
if (serialPortFD <= 0)
@ -553,6 +591,34 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearDTR(JNI
return (ioctl(serialPortFD, TIOCMBIC, &modemBits) == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_presetDTR(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
// Send a system command to preset the DTR mode of the serial port
char commandString[64];
sprintf(commandString, "stty -f %s hupcl", portName);
int result = system(commandString);
(*env)->ReleaseStringUTFChars(env, portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_preclearDTR(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
// Send a system command to preset the DTR mode of the serial port
char commandString[64];
sprintf(commandString, "stty -f %s -hupcl", portName);
int result = system(commandString);
(*env)->ReleaseStringUTFChars(env, portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCTS(JNIEnv *env, jobject obj, jlong serialPortFD)
{
if (serialPortFD <= 0)

View File

@ -2,7 +2,7 @@
* SerialPort_OSX.c
*
* Created on: Feb 25, 2012
* Last Updated on: Jul 27, 2018
* Last Updated on: Oct 07, 2018
* Author: Will Hedgecock
*
* Copyright (C) 2012-2018 Fazecast, Inc.
@ -46,9 +46,12 @@ jclass serialCommClass;
jmethodID serialCommConstructor;
jfieldID serialPortFdField;
jfieldID comPortField;
jfieldID disableConfigField;
jfieldID friendlyNameField;
jfieldID portDescriptionField;
jfieldID isOpenedField;
jfieldID isDtrEnabledField;
jfieldID isRtsEnabledField;
jfieldID baudRateField;
jfieldID dataBitsField;
jfieldID stopBitsField;
@ -148,6 +151,9 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
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");
disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z");
isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z");
isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z");
baudRateField = (*env)->GetFieldID(env, serialCommClass, "baudRate", "I");
dataBitsField = (*env)->GetFieldID(env, serialCommClass, "dataBits", "I");
stopBitsField = (*env)->GetFieldID(env, serialCommClass, "stopBits", "I");
@ -169,6 +175,8 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
unsigned char isDtrEnabled = (*env)->GetBooleanField(env, obj, isDtrEnabledField);
unsigned char isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField);
// Try to open existing serial port with read/write access
int serialPortFD = -1;
@ -179,6 +187,9 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
fcntl(serialPortFD, F_SETFL, 0);
tcgetattr(serialPortFD, &options);
cfmakeraw(&options);
if (!isDtrEnabled || !isRtsEnabled)
options.c_cflag &= ~HUPCL;
options.c_iflag |= BRKINT;
tcsetattr(serialPortFD, TCSANOW, &options);
// Configure the port parameters and timeouts
@ -211,6 +222,9 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
int stopBitsInt = (*env)->GetIntField(env, obj, stopBitsField);
int parityInt = (*env)->GetIntField(env, obj, parityField);
int flowControl = (*env)->GetIntField(env, obj, flowControlField);
unsigned char configDisabled = (*env)->GetBooleanField(env, obj, disableConfigField);
unsigned char isDtrEnabled = (*env)->GetBooleanField(env, obj, isDtrEnabledField);
unsigned char isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField);
tcflag_t byteSize = (byteSizeInt == 5) ? CS5 : (byteSizeInt == 6) ? CS6 : (byteSizeInt == 7) ? CS7 : CS8;
tcflag_t stopBits = ((stopBitsInt == com_fazecast_jSerialComm_SerialPort_ONE_STOP_BIT) || (stopBitsInt == com_fazecast_jSerialComm_SerialPort_ONE_POINT_FIVE_STOP_BITS)) ? 0 : CSTOPB;
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);
@ -224,6 +238,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
options.c_cflag = (byteSize | stopBits | parity | CLOCAL | CREAD | CTSRTSEnabled);
if (parityInt == com_fazecast_jSerialComm_SerialPort_SPACE_PARITY)
options.c_cflag &= ~PARODD;
if (!isDtrEnabled || !isRtsEnabled)
options.c_cflag &= ~HUPCL;
options.c_iflag &= ~(INPCK | IGNPAR | PARMRK | ISTRIP);
if (byteSizeInt < 8)
options.c_iflag |= ISTRIP;
@ -240,7 +256,7 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
}
// Apply changes
int retVal = tcsetattr(serialPortFD, TCSANOW, &options);
int retVal = configDisabled ? 0 : tcsetattr(serialPortFD, TCSANOW, &options);
ioctl(serialPortFD, TIOCEXCL); // Block non-root users from opening this port
if (baudRateCode == 0) // Set custom baud rate
{
@ -554,6 +570,34 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearRTS(JNI
return (ioctl(serialPortFD, TIOCMBIC, &modemBits) == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_presetRTS(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
// Send a system command to preset the RTS mode of the serial port
char commandString[64];
sprintf(commandString, "stty -f %s hupcl", portName);
int result = system(commandString);
(*env)->ReleaseStringUTFChars(env, portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_preclearRTS(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
// Send a system command to preset the RTS mode of the serial port
char commandString[64];
sprintf(commandString, "stty -f %s -hupcl", portName);
int result = system(commandString);
(*env)->ReleaseStringUTFChars(env, portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_setDTR(JNIEnv *env, jobject obj, jlong serialPortFD)
{
if (serialPortFD <= 0)
@ -570,6 +614,34 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearDTR(JNI
return (ioctl(serialPortFD, TIOCMBIC, &modemBits) == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_presetDTR(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
// Send a system command to preset the DTR mode of the serial port
char commandString[64];
sprintf(commandString, "stty -f %s hupcl", portName);
int result = system(commandString);
(*env)->ReleaseStringUTFChars(env, portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_preclearDTR(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField);
const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL);
// Send a system command to preset the DTR mode of the serial port
char commandString[64];
sprintf(commandString, "stty -f %s -hupcl", portName);
int result = system(commandString);
(*env)->ReleaseStringUTFChars(env, portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCTS(JNIEnv *env, jobject obj, jlong serialPortFD)
{
if (serialPortFD <= 0)

View File

@ -2,9 +2,9 @@
COMPILE = cl
LINK = link
CFLAGS = /c /O2 /GF /GL /MT /EHsc /fp:precise /J /nologo /TP
LDFLAGS = /DLL /LTCG /NOASSEMBLY /NOLOGO /DELAYLOAD:ftd2xx.dll
LDFLAGS = /DLL /LTCG /NOASSEMBLY /NOLOGO
INCLUDES = /I"$(JDK_HOME)/include" /I"$(JDK_HOME)/include/win32"
LIBRARIES = Advapi32.lib SetupAPI.lib DelayImp.lib
LIBRARIES = Advapi32.lib SetupAPI.lib
DELETE = @del /q /f
RMDIR = @rd /q /s
MKDIR = @md
@ -44,23 +44,18 @@ all :
$(PRINT).
# Builds 32-bit Windows libraries
win32 : checkdirs $(BUILD_DIR)\x86\$(LIBRARY_NAME)
$(DELETE) $(BUILD_DIR)\x86\*.obj
$(COPY) $(BUILD_DIR)\x86\*.* $(RESOURCE_DIR)\x86
$(COPY) ftdi\ftd2xx32.dll $(RESOURCE_DIR)\x86\ftd2xx.dll
win32 : $(BUILD_DIR)\x86 $(BUILD_DIR)\x86\$(LIBRARY_NAME)
$(COPY) $(BUILD_DIR)\x86\*.dll $(RESOURCE_DIR)\x86
$(DELETE) ..\*.h
$(RMDIR) $(BUILD_DIR)\..
# Builds 64-bit Windows libraries
win64 : checkdirs $(BUILD_DIR)\x86_64\$(LIBRARY_NAME)
$(DELETE) $(BUILD_DIR)\x86_64\*.obj
$(COPY) $(BUILD_DIR)\x86_64\*.* $(RESOURCE_DIR)\x86_64
$(COPY) ftdi\ftd2xx64.dll $(RESOURCE_DIR)\x86_64\ftd2xx.dll
win64 : $(BUILD_DIR)\x86_64 $(BUILD_DIR)\x86_64\$(LIBRARY_NAME)
$(COPY) $(BUILD_DIR)\x86_64\*.dll $(RESOURCE_DIR)\x86_64
$(DELETE) ..\*.h
$(RMDIR) $(BUILD_DIR)\..
# Rule to create build directories
checkdirs : $(BUILD_DIR)\x86 $(BUILD_DIR)\x86_64
$(BUILD_DIR)\x86 :
$(MKDIR) "$@"
$(BUILD_DIR)\x86_64 :
@ -68,11 +63,11 @@ $(BUILD_DIR)\x86_64 :
# Rule to build 32-bit library
$(BUILD_DIR)\x86\$(LIBRARY_NAME) : $(JNI_HEADER) $(OBJECTSx86)
$(LINK) $(LDFLAGS) /MACHINE:X86 /OUT:$@ $(OBJECTSx86) $(LIBRARIES) ftdi/ftd2xx32.lib
$(LINK) $(LDFLAGS) /MACHINE:X86 /OUT:$@ $(OBJECTSx86) $(LIBRARIES)
# Rule to build 64-bit library
$(BUILD_DIR)\x86_64\$(LIBRARY_NAME) : $(JNI_HEADER) $(OBJECTSx86_64)
$(LINK) $(LDFLAGS) /MACHINE:X64 /OUT:$@ $(OBJECTSx86_64) $(LIBRARIES) ftdi/ftd2xx64.lib
$(LINK) $(LDFLAGS) /MACHINE:X64 /OUT:$@ $(OBJECTSx86_64) $(LIBRARIES)
# Suffix rules to get from *.c -> *.obj
$(OBJECTSx86_64) :

View File

@ -2,7 +2,7 @@
* SerialPort_Windows.c
*
* Created on: Feb 25, 2012
* Last Updated on: Sep 25, 2018
* Last Updated on: Oct 07, 2018
* Author: Will Hedgecock
*
* Copyright (C) 2012-2018 Fazecast, Inc.
@ -47,47 +47,27 @@ jfieldID comPortField;
jfieldID friendlyNameField;
jfieldID portDescriptionField;
jfieldID isOpenedField;
jfieldID disableConfigField;
jfieldID isDtrEnabledField;
jfieldID isRtsEnabledField;
jfieldID baudRateField;
jfieldID dataBitsField;
jfieldID stopBitsField;
jfieldID parityField;
jfieldID flowControlField;
jfieldID sendDeviceQueueSizeField;
jfieldID receiveDeviceQueueSizeField;
jfieldID timeoutModeField;
jfieldID readTimeoutField;
jfieldID writeTimeoutField;
jfieldID eventFlagsField;
// FTDI DLL library loader
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
HINSTANCE hDllInstance = (HINSTANCE)&__ImageBase;
HMODULE LocalLoadLibrary(LPCSTR pszModuleName)
{
CHAR szPath[MAX_PATH] = "";
DWORD cchPath = GetModuleFileNameA(hDllInstance, szPath, MAX_PATH);
while (cchPath > 0)
{
switch(szPath[cchPath - 1])
{
case '\\':
case '/':
case ':':
break;
default:
--cchPath;
continue;
}
break;
}
lstrcpynA(szPath + cchPath, pszModuleName, MAX_PATH - cchPath);
return LoadLibraryA(szPath);
}
FARPROC WINAPI DllLoadNotifyHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
if (dliNotify == dliNotePreLoadLibrary)
return (FARPROC)LocalLoadLibrary(pdli->szDll);
return NULL;
}
extern "C" const PfnDliHook __pfnDliNotifyHook2 = DllLoadNotifyHook;
// Run-time loadable DLL function
typedef int (__cdecl *FT_CreateDeviceInfoListFunction)(LPDWORD);
typedef int (__cdecl *FT_GetDeviceInfoListFunction)(FT_DEVICE_LIST_INFO_NODE*, LPDWORD);
typedef int (__cdecl *FT_GetComPortNumberFunction)(FT_HANDLE, LPLONG);
typedef int (__cdecl *FT_OpenFunction)(int, FT_HANDLE*);
typedef int (__cdecl *FT_CloseFunction)(FT_HANDLE);
JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommPorts(JNIEnv *env, jclass serialComm)
{
@ -286,35 +266,48 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP
}
// Attempt to locate any FTDI-specified port descriptions
DWORD numDevs;
if ((FT_CreateDeviceInfoList(&numDevs) == FT_OK) && (numDevs > 0))
HINSTANCE ftdiLibInstance = LoadLibrary(TEXT("ftd2xx.dll"));
if (ftdiLibInstance != NULL)
{
FT_DEVICE_LIST_INFO_NODE *devInfo = (FT_DEVICE_LIST_INFO_NODE*)malloc(sizeof(FT_DEVICE_LIST_INFO_NODE)*numDevs);
if (FT_GetDeviceInfoList(devInfo, &numDevs) == FT_OK)
FT_CreateDeviceInfoListFunction FT_CreateDeviceInfoList = (FT_CreateDeviceInfoListFunction)GetProcAddress(ftdiLibInstance, "FT_CreateDeviceInfoList");
FT_GetDeviceInfoListFunction FT_GetDeviceInfoList = (FT_GetDeviceInfoListFunction)GetProcAddress(ftdiLibInstance, "FT_GetDeviceInfoList");
FT_GetComPortNumberFunction FT_GetComPortNumber = (FT_GetComPortNumberFunction)GetProcAddress(ftdiLibInstance, "FT_GetComPortNumber");
FT_OpenFunction FT_Open = (FT_OpenFunction)GetProcAddress(ftdiLibInstance, "FT_Open");
FT_CloseFunction FT_Close = (FT_CloseFunction)GetProcAddress(ftdiLibInstance, "FT_Close");
if ((FT_CreateDeviceInfoList != NULL) && (FT_GetDeviceInfoList != NULL) && (FT_GetComPortNumber != NULL) && (FT_Open != NULL) && (FT_Close != NULL))
{
int i, j;
wchar_t comPortString[128];
for (i = 0; i < numDevs; ++i)
DWORD numDevs;
if ((FT_CreateDeviceInfoList(&numDevs) == FT_OK) && (numDevs > 0))
{
LONG comPortNumber = 0;
if ((FT_Open(i, &devInfo[i].ftHandle) == FT_OK) && (FT_GetComPortNumber(devInfo[i].ftHandle, &comPortNumber) == FT_OK))
FT_DEVICE_LIST_INFO_NODE *devInfo = (FT_DEVICE_LIST_INFO_NODE*)malloc(sizeof(FT_DEVICE_LIST_INFO_NODE)*numDevs);
if (FT_GetDeviceInfoList(devInfo, &numDevs) == FT_OK)
{
// Update port description if COM port is actually connected and present in the port list
FT_Close(devInfo[i].ftHandle);
swprintf(comPortString, sizeof(comPortString) / sizeof(wchar_t), L"COM%ld", comPortNumber);
for (j = 0; j < serialCommPorts.length; ++j)
if (wcscmp(serialCommPorts.first[j], comPortString) == 0)
int i, j;
wchar_t comPortString[128];
for (i = 0; i < numDevs; ++i)
{
LONG comPortNumber = 0;
if ((FT_Open(i, &devInfo[i].ftHandle) == FT_OK) && (FT_GetComPortNumber(devInfo[i].ftHandle, &comPortNumber) == FT_OK))
{
size_t descLength = 8+strlen(devInfo[i].Description);
free(serialCommPorts.third[j]);
serialCommPorts.third[j] = (wchar_t*)malloc(descLength*sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, devInfo[i].Description, -1, serialCommPorts.third[j], descLength);
break;
// Update port description if COM port is actually connected and present in the port list
FT_Close(devInfo[i].ftHandle);
swprintf(comPortString, sizeof(comPortString) / sizeof(wchar_t), L"COM%ld", comPortNumber);
for (j = 0; j < serialCommPorts.length; ++j)
if (wcscmp(serialCommPorts.first[j], comPortString) == 0)
{
size_t descLength = 8+strlen(devInfo[i].Description);
free(serialCommPorts.third[j]);
serialCommPorts.third[j] = (wchar_t*)malloc(descLength*sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, devInfo[i].Description, -1, serialCommPorts.third[j], descLength);
break;
}
}
}
}
free(devInfo);
}
}
free(devInfo);
FreeLibrary(ftdiLibInstance);
}
// Get relevant SerialComm methods and fill in com port array
@ -355,11 +348,16 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
friendlyNameField = env->GetFieldID(serialCommClass, "friendlyName", "Ljava/lang/String;");
portDescriptionField = env->GetFieldID(serialCommClass, "portDescription", "Ljava/lang/String;");
isOpenedField = env->GetFieldID(serialCommClass, "isOpened", "Z");
disableConfigField = env->GetFieldID(serialCommClass, "disableConfig", "Z");
isDtrEnabledField = env->GetFieldID(serialCommClass, "isDtrEnabled", "Z");
isRtsEnabledField = env->GetFieldID(serialCommClass, "isRtsEnabled", "Z");
baudRateField = env->GetFieldID(serialCommClass, "baudRate", "I");
dataBitsField = env->GetFieldID(serialCommClass, "dataBits", "I");
stopBitsField = env->GetFieldID(serialCommClass, "stopBits", "I");
parityField = env->GetFieldID(serialCommClass, "parity", "I");
flowControlField = env->GetFieldID(serialCommClass, "flowControl", "I");
sendDeviceQueueSizeField = env->GetFieldID(serialCommClass, "sendDeviceQueueSize", "I");
receiveDeviceQueueSizeField = env->GetFieldID(serialCommClass, "receiveDeviceQueueSize", "I");
timeoutModeField = env->GetFieldID(serialCommClass, "timeoutMode", "I");
readTimeoutField = env->GetFieldID(serialCommClass, "readTimeout", "I");
writeTimeoutField = env->GetFieldID(serialCommClass, "writeTimeout", "I");
@ -413,6 +411,11 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
int stopBitsInt = env->GetIntField(obj, stopBitsField);
int parityInt = env->GetIntField(obj, parityField);
int flowControl = env->GetIntField(obj, flowControlField);
DWORD sendDeviceQueueSize = (DWORD)env->GetIntField(obj, sendDeviceQueueSizeField);
DWORD receiveDeviceQueueSize = (DWORD)env->GetIntField(obj, receiveDeviceQueueSizeField);
BYTE configDisabled = (BYTE)env->GetBooleanField(obj, disableConfigField);
BYTE isDtrEnabled = env->GetBooleanField(obj, isDtrEnabledField);
BYTE isRtsEnabled = env->GetBooleanField(obj, isRtsEnabledField);
BYTE stopBits = (stopBitsInt == com_fazecast_jSerialComm_SerialPort_ONE_STOP_BIT) ? ONESTOPBIT : (stopBitsInt == com_fazecast_jSerialComm_SerialPort_ONE_POINT_FIVE_STOP_BITS) ? ONE5STOPBITS : TWOSTOPBITS;
BYTE parity = (parityInt == com_fazecast_jSerialComm_SerialPort_NO_PARITY) ? NOPARITY : (parityInt == com_fazecast_jSerialComm_SerialPort_ODD_PARITY) ? ODDPARITY : (parityInt == com_fazecast_jSerialComm_SerialPort_EVEN_PARITY) ? EVENPARITY : (parityInt == com_fazecast_jSerialComm_SerialPort_MARK_PARITY) ? MARKPARITY : SPACEPARITY;
BOOL isParity = (parityInt == com_fazecast_jSerialComm_SerialPort_NO_PARITY) ? FALSE : TRUE;
@ -420,13 +423,14 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_RTS_ENABLED) > 0));
BOOL DSREnabled = (((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_DSR_ENABLED) > 0) ||
((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_DTR_ENABLED) > 0));
BYTE DTRValue = ((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_DTR_ENABLED) > 0) ? DTR_CONTROL_HANDSHAKE : DTR_CONTROL_ENABLE;
BYTE RTSValue = ((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_RTS_ENABLED) > 0) ? RTS_CONTROL_HANDSHAKE : RTS_CONTROL_ENABLE;
BYTE DTRValue = ((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_DTR_ENABLED) > 0) ? DTR_CONTROL_HANDSHAKE : (isDtrEnabled ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE);
BYTE RTSValue = ((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_RTS_ENABLED) > 0) ? RTS_CONTROL_HANDSHAKE : (isRtsEnabled ? RTS_CONTROL_ENABLE : RTS_CONTROL_DISABLE);
BOOL XonXoffInEnabled = ((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_XONXOFF_IN_ENABLED) > 0);
BOOL XonXoffOutEnabled = ((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_XONXOFF_OUT_ENABLED) > 0);
// Retrieve existing port configuration
if (!GetCommState(serialPortHandle, &dcbSerialParams))
SetupComm(serialPortHandle, receiveDeviceQueueSize, sendDeviceQueueSize);
if (!configDisabled && !GetCommState(serialPortHandle, &dcbSerialParams))
return JNI_FALSE;
// Set updated port parameters
@ -454,7 +458,8 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(J
dcbSerialParams.XoffChar = (char)19;
// Apply changes
return SetCommState(serialPortHandle, &dcbSerialParams) && Java_com_fazecast_jSerialComm_SerialPort_configEventFlags(env, obj, serialPortFD);
return (configDisabled ? Java_com_fazecast_jSerialComm_SerialPort_configEventFlags(env, obj, serialPortFD) :
(SetCommState(serialPortHandle, &dcbSerialParams) && Java_com_fazecast_jSerialComm_SerialPort_configEventFlags(env, obj, serialPortFD)));
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeouts(JNIEnv *env, jobject obj, jlong serialPortFD)
@ -783,6 +788,44 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearRTS(JNI
return EscapeCommFunction(serialPortHandle, CLRRTS);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_presetRTS(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)env->GetObjectField(obj, comPortField);
const char *portName = env->GetStringUTFChars(portNameJString, NULL);
const char* comPort = strrchr(portName, '\\');
// Try to preset the RTS mode of the COM port using a Windows command
int result = -1;
if (comPort != NULL)
{
char commandString[32];
sprintf(commandString, "MODE %s rts=on", comPort + 1);
result = system(commandString);
}
env->ReleaseStringUTFChars(portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_preclearRTS(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)env->GetObjectField(obj, comPortField);
const char *portName = env->GetStringUTFChars(portNameJString, NULL);
const char* comPort = strrchr(portName, '\\');
// Try to preset the RTS mode of the COM port using a Windows command
int result = -1;
if (comPort != NULL)
{
char commandString[32];
sprintf(commandString, "MODE %s rts=off", comPort + 1);
result = system(commandString);
}
env->ReleaseStringUTFChars(portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_setDTR(JNIEnv *env, jobject obj, jlong serialPortFD)
{
HANDLE serialPortHandle = (HANDLE)serialPortFD;
@ -799,6 +842,44 @@ JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearDTR(JNI
return EscapeCommFunction(serialPortHandle, CLRDTR);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_presetDTR(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)env->GetObjectField(obj, comPortField);
const char *portName = env->GetStringUTFChars(portNameJString, NULL);
const char* comPort = strrchr(portName, '\\');
// Try to preset the DTR mode of the COM port using a Windows command
int result = -1;
if (comPort != NULL)
{
char commandString[32];
sprintf(commandString, "MODE %s dtr=on", comPort + 1);
result = system(commandString);
}
env->ReleaseStringUTFChars(portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_preclearDTR(JNIEnv *env, jobject obj)
{
jstring portNameJString = (jstring)env->GetObjectField(obj, comPortField);
const char *portName = env->GetStringUTFChars(portNameJString, NULL);
const char* comPort = strrchr(portName, '\\');
// Try to preset the DTR mode of the COM port using a Windows command
int result = -1;
if (comPort != NULL)
{
char commandString[32];
sprintf(commandString, "MODE %s dtr=off", comPort + 1);
result = system(commandString);
}
env->ReleaseStringUTFChars(portNameJString, portName);
return (result == 0);
}
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCTS(JNIEnv *env, jobject obj, jlong serialPortFD)
{
HANDLE serialPortHandle = (HANDLE)serialPortFD;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,7 +2,7 @@
* SerialPort.java
*
* Created on: Feb 25, 2012
* Last Updated on: Aug 20, 2018
* Last Updated on: Oct 07, 2018
* Author: Will Hedgecock
*
* Copyright (C) 2012-2018 Fazecast, Inc.
@ -42,7 +42,7 @@ import java.util.Date;
* This class provides native access to serial ports and devices without requiring external libraries or tools.
*
* @author Will Hedgecock &lt;will.hedgecock@fazecast.com&gt;
* @version 2.2.3
* @version 2.3.0
* @see java.io.InputStream
* @see java.io.OutputStream
*/
@ -203,29 +203,6 @@ public final class SerialPort
tempNativeLibrary.deleteOnExit();
try
{
// Copy the FTDI driver library to the system temp directory if on Windows
if (isWindows)
{
String ftdiFileName = tempFileDirectory + "ftd2xx.dll";
File tempFtdiLibrary = new File(ftdiFileName);
InputStream ftdiContents = SerialPort.class.getResourceAsStream("/" + libraryPath + "/ftd2xx.dll");
if (ftdiContents != null)
{
try
{
FileOutputStream destinationFileContents = new FileOutputStream(tempFtdiLibrary);
byte transferBuffer[] = new byte[4096];
int numBytesRead;
while ((numBytesRead = ftdiContents.read(transferBuffer)) > 0)
destinationFileContents.write(transferBuffer, 0, numBytesRead);
destinationFileContents.close();
}
catch (FileNotFoundException e) {};
ftdiContents.close();
}
}
// Load the native jSerialComm library
InputStream fileContents = SerialPort.class.getResourceAsStream("/" + libraryPath + "/" + fileName);
if (fileContents == null)
@ -270,10 +247,7 @@ public final class SerialPort
* @return The port description as reported by the device itself.
*/
@Override
public String toString()
{
return getPortDescription();
}
public String toString() { return getPortDescription(); }
/**
* Returns a list of all available serial ports on this machine.
@ -334,40 +308,6 @@ public final class SerialPort
return serialPort;
}
// /**
// * Allocates a {@link SerialPort} object corresponding to a previously opened serial port file descriptor.
// * <p>
// * Using this method to create a {@link SerialPort} object may not allow you to change some port characteristics
// * like baud rate, flow control, or parity, depending on the methodology that was used to initially open the native
// * file descriptor.
// * <p>
// * Use of this constructor is not recommended <b>except</b> for use with Android-specific applications. In this
// * case, you can use the Android USB Host APIs to allow the user to grant permission to use the port, and then
// * return the native file descriptor to this library via the Android UsbDeviceConnection.getFileDescriptor() method.
// * <p>
// * For non-Android applications, any of the other constructors are recommended; however, this method may still be
// * used if you have a specific need for it in your application.
// *
// * @param nativeFileDescriptor A pre-opened file descriptor corresponding to the serial port you would like to use with this library.
// * @return A SerialPort object.
// */
/* static public SerialPort getCommPort(long nativeFileDescriptor)
{
// Create SerialPort object and associate it with the native file descriptor
SerialPort serialPort = new SerialPort();
if (!serialPort.associateNativeHandle(nativeFileDescriptor))
serialPort.comPort = "UNKNOWN";
serialPort.portString = "User-Specified Port";
serialPort.portHandle = nativeFileDescriptor;
serialPort.isOpened = true;
// Create the Input/OutputStream interfaces
serialPort.inputStream = serialPort.new SerialPortInputStream();
serialPort.outputStream = serialPort.new SerialPortOutputStream();
return serialPort;
}*/
// Parity Values
static final public int NO_PARITY = 0;
static final public int ODD_PARITY = 1;
@ -406,28 +346,33 @@ public final class SerialPort
private volatile long portHandle = -1;
private volatile int baudRate = 9600, dataBits = 8, stopBits = ONE_STOP_BIT, parity = NO_PARITY, eventFlags = 0;
private volatile int timeoutMode = TIMEOUT_NONBLOCKING, readTimeout = 0, writeTimeout = 0, flowControl = 0;
private volatile int sendDeviceQueueSize = 4096, receiveDeviceQueueSize = 4096;
private volatile SerialPortInputStream inputStream = null;
private volatile SerialPortOutputStream outputStream = null;
private volatile SerialPortDataListener userDataListener = null;
private volatile SerialPortEventListener serialEventListener = null;
private volatile String comPort, friendlyName, portDescription;
private volatile boolean isOpened = false;
private volatile boolean isOpened = false, disableConfig = false, isRtsEnabled = true, isDtrEnabled = true;
/**
* Opens this serial port for reading and writing with an optional delay time.
* <p>
* All serial port parameters or timeouts can be changed at any time before or after the port has been opened.
* <p>
* Note that calling this method on an already opened port will simply return a value of true.
* Note that calling this method on an already opened port will simply reconfigure the port parameters.
*
* @param safetySleepTime The number of milliseconds to sleep before opening the port in case of frequent closing/openings.
* @param deviceSendQueueSize The requested size in bytes of the internal device driver's output queue (only has an effect on Windows)
* @param deviceReceiveQueueSize The requested size in bytes of the internal device driver's input queue (only has an effect on Windows)
* @return Whether the port was successfully opened.
*/
public final boolean openPort(int safetySleepTime)
public final boolean openPort(int safetySleepTime, int deviceSendQueueSize, int deviceReceiveQueueSize)
{
// Return true if already opened
// Set the send/receive internal buffer sizes, and return true if already opened
sendDeviceQueueSize = deviceSendQueueSize;
receiveDeviceQueueSize = deviceReceiveQueueSize;
if (isOpened)
return true;
return configPort(portHandle);
// Force a sleep to ensure that the port does not become unusable due to rapid closing/opening on the part of the user
if (safetySleepTime > 0)
@ -474,6 +419,18 @@ public final class SerialPort
return isOpened;
}
/**
* Opens this serial port for reading and writing with an optional delay time.
* <p>
* All serial port parameters or timeouts can be changed at any time before or after the port has been opened.
* <p>
* Note that calling this method on an already opened port will simply reconfigure the port parameters.
*
* @param safetySleepTime The number of milliseconds to sleep before opening the port in case of frequent closing/openings.
* @return Whether the port was successfully opened.
*/
public final boolean openPort(int safetySleepTime) { return openPort(safetySleepTime, sendDeviceQueueSize, receiveDeviceQueueSize); }
/**
* Opens this serial port for reading and writing.
* <p>
@ -481,7 +438,7 @@ public final class SerialPort
* <p>
* All serial port parameters or timeouts can be changed at any time before or after the port has been opened.
* <p>
* Note that calling this method on an already opened port will simply return a value of true.
* Note that calling this method on an already opened port will simply reconfigure the port parameters.
*
* @return Whether the port was successfully opened.
*/
@ -514,6 +471,15 @@ public final class SerialPort
*/
public final boolean isOpen() { return isOpened; }
/**
* Disable the library from calling any of the underlying device driver configuration methods.
* <p>
* This function should never be called except in very specific cases involving USB-to-Serial converters
* with buggy device drivers. In that case, this function <b>must</b> be called before attempting to
* open the port.
*/
public final void disablePortConfiguration() { disableConfig = true; }
// Serial Port Setup Methods
private static native void initializeLibrary(); // Initializes the JNI code
private static native void uninitializeLibrary(); // Un-initializes the JNI code
@ -531,8 +497,12 @@ public final class SerialPort
private final native boolean clearBreak(long portHandle); // Clear BREAK status on serial line
private final native boolean setRTS(long portHandle); // Set RTS line to 1
private final native boolean clearRTS(long portHandle); // Clear RTS line to 0
private final native boolean presetRTS(); // Set RTS line to 1 prior to opening
private final native boolean preclearRTS(); // Clear RTS line to 0 prior to opening
private final native boolean setDTR(long portHandle); // Set DTR line to 1
private final native boolean clearDTR(long portHandle); // Clear DTR line to 0
private final native boolean presetDTR(); // Set DTR line to 1 prior to opening
private final native boolean preclearDTR(); // Clear DTR line to 0 prior to opening
private final native boolean getCTS(long portHandle); // Returns whether the CTS signal is 1
private final native boolean getDSR(long portHandle); // Returns whether the DSR signal is 1
@ -631,25 +601,41 @@ public final class SerialPort
* Sets the state of the RTS line to 1.
* @return true if successful, false if not.
*/
public final boolean setRTS() { return setRTS(portHandle); }
public final boolean setRTS()
{
isRtsEnabled = true;
return (isOpened ? setRTS(portHandle) : presetRTS());
}
/**
* Clears the state of the RTS line to 0.
* @return true if successful, false if not.
*/
public final boolean clearRTS() { return clearRTS(portHandle); }
public final boolean clearRTS()
{
isRtsEnabled = false;
return (isOpened ? clearRTS(portHandle) : preclearRTS());
}
/**
* Sets the state of the DTR line to 1.
* @return true if successful, false if not.
*/
public final boolean setDTR() { return setDTR(portHandle); }
public final boolean setDTR()
{
isDtrEnabled = true;
return (isOpened ? setDTR(portHandle) : presetDTR());
}
/**
* Clears the state of the DTR line to 0.
* @return true if successful, false if not.
*/
public final boolean clearDTR() { return clearDTR(portHandle); }
public final boolean clearDTR()
{
isDtrEnabled = false;
return (isOpened ? clearDTR(portHandle) : preclearDTR());
}
/**
* Returns whether the CTS line is currently asserted.

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 2.2.3
* @version 2.3.0
* @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 2.2.3
* @version 2.3.0
* @see java.util.EventObject
*/
public final class SerialPortEvent extends EventObject

View File

@ -31,7 +31,7 @@ import java.io.IOException;
* This class describes a serial port IO exception.
*
* @author Will Hedgecock &lt;will.hedgecock@fazecast.com&gt;
* @version 2.2.3
* @version 2.3.0
* @see java.io.IOException
*/
public final class SerialPortIOException extends IOException

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 2.2.3
* @version 2.3.0
* @see com.fazecast.jSerialComm.SerialPortDataListener
* @see java.util.EventListener
*/

View File

@ -31,7 +31,7 @@ import java.io.InterruptedIOException;
* This class describes a serial port timeout exception.
*
* @author Will Hedgecock &lt;will.hedgecock@fazecast.com&gt;
* @version 2.2.3
* @version 2.3.0
* @see java.io.InterruptedIOException
*/
public final class SerialPortTimeoutException extends InterruptedIOException

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 2.2.3
* @version 2.3.0
* @see java.io.InputStream
* @see java.io.OutputStream
*/