Find file
Fetching contributors…
Cannot retrieve contributors at this time
1643 lines (1420 sloc) 48 KB
/*-------------------------------------------------------------------------
| rxtx is a native interface to serial ports in java.
| Copyright 2002 Michal Hobot MichalHobot@netscape.net
| Copyright 1997-2002 by Trent Jarvi taj@www.linux.org.uk
|
| This library 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 2.1 of the License, or (at your option) any later version.
|
| This library 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.
|
| The following has been added to allow RXTX to be distributed with Sun
| Microsystem's CommAPI library as suggested by the FSF.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| A program that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being compiled or linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface, regardless of
| the license terms of these independent modules, and to copy and distribute
| the resulting combined work under terms of your choice, provided that
| every copy of the combined work is accompanied by a complete copy of
| the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--------------------------------------------------------------------------*/
#include "StdAfx.h"
#include "rxtxHelpers.h"
/*
Initialize
accept: none
perform: Initialize the native library
return: none
exceptions: none
comments:
* Class: gnu_io_RXTXPort
* Method: Initialize
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_Initialize(JNIEnv *env, jclass cls)
{
}
/*
open
accept: The device to open. ie "COM1:"
perform: open the device
return: handle
exceptions: IOExcepiton
comments: Very often people complain about not being able to get past
this function and it turns out to be permissions on the
device file or bios has the device disabled.
* Class: gnu_io_RXTXPort
* Method: open
* Signature: (Ljava/lang/String{ })I
*/
JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_open(JNIEnv *env, jobject jobj, jstring name)
{
DCB PortDCB;
COMMTIMEOUTS CommTimeouts;
LPCWSTR lpMsgBuf;
EventInfoStruct *EventInfo;
DWORD dwErr;
LPCWSTR wszName = env->GetStringChars(name, NULL);
HANDLE hPort = CreateFileW(wszName, // Pointer to the name of the port
GENERIC_READ | GENERIC_WRITE,// Access (read-write) mode
0, // Share mode
NULL, // Pointer to the security attribute
OPEN_EXISTING,// How to open the serial port
0, // Port attributes
NULL); // Handle to port with attribute to copy
// If it fails to open the port, return FALSE.
if ( hPort == INVALID_HANDLE_VALUE )
{ // Could not open the port.
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, PORT_IN_USE_EXCEPTION, L"open - CreateFile", lpMsgBuf );
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
env->ReleaseStringChars(name, wszName);
return (jint)INVALID_HANDLE_VALUE;
}
PortDCB.DCBlength = sizeof (DCB);
// Get the default port setting information.
GetCommState(hPort, &PortDCB);
// Change the DCB structure settings.
PortDCB.fBinary = TRUE; // Binary mode; no EOF check
PortDCB.fParity = TRUE; // Enable parity checking
PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control
PortDCB.fDtrControl = DTR_CONTROL_HANDSHAKE;// DTR flow control type
PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity
PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx
PortDCB.fErrorChar = FALSE; // Disable error replacement
PortDCB.fNull = FALSE; // Disable null stripping
PortDCB.fRtsControl = RTS_CONTROL_ENABLE;// RTS flow control
PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes on error
// Configure the port according to the specifications of the DCB structure.
if (!SetCommState(hPort, &PortDCB))
{ // Could not set comm port state
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, PORT_IN_USE_EXCEPTION, L"open - SetCommState", lpMsgBuf);
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
env->ReleaseStringChars(name, wszName);
return (jint)INVALID_HANDLE_VALUE;
}
// Retrieve the time-out parameters for all read and write operations
// on the port.
GetCommTimeouts(hPort, &CommTimeouts);
// Change the COMMTIMEOUTS structure settings.
CommTimeouts.ReadIntervalTimeout = 0;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = MAXDWORD;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
// Set the time-out parameters for all read and write operations
// on the port.
if (!SetCommTimeouts(hPort, &CommTimeouts))
{ // Unable to set the time-out parameters
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, PORT_IN_USE_EXCEPTION, L"open - SetCommTimeouts", lpMsgBuf);
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
env->ReleaseStringChars(name, wszName);
return (jint)INVALID_HANDLE_VALUE;
}
// SETRTS: Sends the RTS (request-to-send) signal.
EscapeCommFunction(hPort, SETRTS);
if(dwErr = InitialiseEventInfoStruct(hPort, &EventInfo))
{ // Unable to set up EventInfo structure for event processing
CreateErrorMsg(dwErr, lpMsgBuf);
throw_java_exceptionW(env, IO_EXCEPTION, L"open - InitialiseEventInfoStruct", lpMsgBuf);
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
env->ReleaseStringChars(name, wszName);
return (jint)INVALID_HANDLE_VALUE;
}
jclass cls = env->GetObjectClass(jobj);
jfieldID jfEis = env->GetFieldID(cls, "eis", "I");
if( !jfEis ) {
IF_DEBUG
(
env->ExceptionDescribe();
)
env->ExceptionClear();
// Free the buffers.
env->ReleaseStringChars(name, wszName);
return (jint)INVALID_HANDLE_VALUE;
}
env->SetIntField(jobj, jfEis, (jint)EventInfo);
env->ReleaseStringChars(name, wszName);
// Returning HANDLE (which is a pointer) as file descriptor... Anyway, 32 bits are 32 bits
return (jint)hPort;
}
/*
nativeSetSerialPortParams
accept: speed, data bits, stop bits, parity
perform: set the serial port parameters
return: void
exceptions: UnsupportedCommOperationException
* Class: gnu_io_RXTXPort
* Method: nativeSetSerialPortParams
* Signature: (IIII)V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_nativeSetSerialPortParams(JNIEnv *env, jobject jobj, jint speed, jint dataBits, jint stopBits, jint parity)
{
DCB PortDCB;
LPCWSTR lpMsgBuf;
HANDLE hPort = get_fd(env, jobj);
PortDCB.DCBlength = sizeof(DCB);
IF_DEBUG
(
printj(env, L"--- RXTXPort.nativeSetSerialPortParams(%ld, %ld, %ld, %ld) called\n", speed, dataBits, stopBits, parity);
)
// Get the default port setting information.
if(!GetCommState(hPort, &PortDCB))
{ //Unable to get configuration of the serial port
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetSerialPortParams - GetCommState", lpMsgBuf);
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
return;
}
// Change the DCB structure settings.
PortDCB.BaudRate = speed; // Current baud
PortDCB.ByteSize = (BYTE)dataBits; // Number of bits/byte, 4-8
PortDCB.Parity = (BYTE)parity; // 0-4=no,odd,even,mark,space
switch(stopBits)
{
case gnu_io_RXTXPort_STOPBITS_1:
PortDCB.StopBits = ONESTOPBIT;
break;
case gnu_io_RXTXPort_STOPBITS_2:
PortDCB.StopBits = TWOSTOPBITS;
break;
case gnu_io_RXTXPort_STOPBITS_1_5:
PortDCB.StopBits = ONE5STOPBITS;
break;
default:
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetSerialPortParams", L"Incorrect stopBits");
}
// Configure the port according to the specifications of the DCB structure.
if (!SetCommState (hPort, &PortDCB))
{ //Unable to configure the serial port
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetSerialPortParams - SetCommState", lpMsgBuf);
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
return;
}
}
/*
setflowcontrol
accept: flowmode
FLOWCONTROL_NONE none
FLOWCONTROL_RTSCTS_IN hardware flow control
FLOWCONTROL_RTSCTS_OUT ""
FLOWCONTROL_XONXOFF_IN input software flow control
FLOWCONTROL_XONXOFF_OUT output software flow control
perform: set flow control to flowmode
return: none
exceptions: UnsupportedCommOperationException
comments: there is no differentiation between input and output hardware
flow control
* Class: gnu_io_RXTXPort
* Method: setflowcontrol
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_setflowcontrol(JNIEnv *env, jobject jobj, jint flowcontrol)
{
DCB PortDCB;
LPCWSTR lpMsgBuf;
IF_DEBUG
(
printj(env, L"--- RXTXPort.setflowcontrol(%ld) called\n", flowcontrol);
)
HANDLE hPort = get_fd(env, jobj);
PortDCB.DCBlength = sizeof(DCB);
if(!GetCommState (hPort, &PortDCB))
{ //Unable to get configuration of the serial port
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"setflowcontrol - GetCommState", lpMsgBuf);
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
return;
}
if(flowcontrol & (gnu_io_RXTXPort_FLOWCONTROL_RTSCTS_IN | gnu_io_RXTXPort_FLOWCONTROL_RTSCTS_OUT))
PortDCB.fRtsControl = RTS_CONTROL_HANDSHAKE;
else
PortDCB.fRtsControl = RTS_CONTROL_ENABLE;
if(flowcontrol & gnu_io_RXTXPort_FLOWCONTROL_RTSCTS_OUT)
PortDCB.fOutxCtsFlow = TRUE;
else
PortDCB.fOutxCtsFlow = FALSE;
if(flowcontrol & gnu_io_RXTXPort_FLOWCONTROL_XONXOFF_IN)
PortDCB.fInX = TRUE;
else
PortDCB.fInX = FALSE;
if(flowcontrol & gnu_io_RXTXPort_FLOWCONTROL_XONXOFF_OUT)
PortDCB.fOutX = TRUE;
else
PortDCB.fOutX = FALSE;
// Configure the port according to the specifications of the DCB structure.
if (!SetCommState (hPort, &PortDCB))
{ // Could not set params
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"setflowcontrol - SetCommState", lpMsgBuf);
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
return;
}
}
/*
NativegetReceiveTimeout
accept: none
perform: get termios.c_cc[VTIME]
return: VTIME
comments: see NativeEnableReceiveTimeoutThreshold
* Class: gnu_io_RXTXPort
* Method: NativegetReceiveTimeout
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_NativegetReceiveTimeout(JNIEnv *env, jobject jobj)
{
COMMTIMEOUTS CommTimeouts;
LPCWSTR lpMsgBuf;
HANDLE hPort = get_fd(env, jobj);
IF_DEBUG
(
printj(env, L"--- RXTXPort.NativegetReceiveTimeout() called\n");
)
// Retrieve the time-out parameters for all read and write operations on the port.
if (!GetCommTimeouts(hPort, &CommTimeouts))
{ // Unable to get the time-out parameters
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, IO_EXCEPTION, L"NativegetReceiveTimeout - GetCommTimeouts", lpMsgBuf);
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
return -1;
}
// As far as I know c_cc is byte table
return CommTimeouts.ReadIntervalTimeout/100 <= 255 ? CommTimeouts.ReadIntervalTimeout / 100 : 255;
}
/*
NativeisReceiveTimeoutEnabled
accept: none
perform: determine if VTIME is none 0
return: JNI_TRUE if VTIME > 0 else JNI_FALSE
comments: see NativeEnableReceiveTimeoutThreshold
* Class: gnu_io_RXTXPort
* Method: NativeisReceiveTimeoutEnabled
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_NativeisReceiveTimeoutEnabled(JNIEnv *env, jobject jobj)
{
COMMTIMEOUTS CommTimeouts;
LPCWSTR lpMsgBuf;
HANDLE hPort = get_fd(env, jobj);
IF_DEBUG
(
printj(env, L"--- RXTXPort.NativeisReceiveTimeoutEnabled() called\n");
)
// Retrieve the time-out parameters for all read and write operations
// on the port.
if (!GetCommTimeouts(hPort, &CommTimeouts))
{ // Unable to get the time-out parameters
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, IO_EXCEPTION, L"NativeisReceiveTimeoutEnabled - GetCommTimeouts", lpMsgBuf);
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
return -1;
}
return CommTimeouts.ReadIntervalTimeout || CommTimeouts.ReadTotalTimeoutConstant || CommTimeouts.ReadTotalTimeoutMultiplier ? JNI_TRUE : JNI_FALSE;
}
/*
NativeEnableReceiveTimeoutThreshold
accept: int threshold, int vtime,int buffer
perform: Set c_cc->VMIN to threshold and c_cc=>VTIME to vtime
return: void
exceptions: IOException
comments: This is actually all handled in read with select in
canonical input mode.
* Class: gnu_io_RXTXPort
* Method: NativeEnableReceiveTimeoutThreshold
* Signature: (III)V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_NativeEnableReceiveTimeoutThreshold(JNIEnv *env, jobject jobj, jint time, jint threshold, jint InputBuffer)
{
COMMTIMEOUTS CommTimeouts;
LPCWSTR lpMsgBuf;
HANDLE hPort = get_fd(env, jobj);
IF_DEBUG
(
printj(env, L"--- RXTXPort.NativeEnableReceiveTimeoutThreshold(%ld, %ld) called\n", time, threshold);
)
// Retrieve the time-out parameters for all read and write operations
// on the port.
if (!GetCommTimeouts(hPort, &CommTimeouts))
{ // Unable to get the time-out parameters
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, IO_EXCEPTION, L"NativeEnableReceiveTimeoutThreshold - GetCommTimeouts", lpMsgBuf);
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
return;
}
/* ------ from javax.comm.CommPort javadoc -------------------------------------------------------------
| Threshold | Timeout |Read Buffer Size | Read Behaviour
|State |Value |State |Value| |
|disabled| - |disabled| - | n bytes | block until any data is available
|enabled |m bytes|disabled| - | n bytes | block until min(m,n) bytes are available
|disabled| - |enabled |x ms | n bytes | block for x ms or until any data is available
|enabled |m bytes|enabled |x ms | n bytes | block for x ms or until min(m,n) bytes are available
--------------------------------------------------------------------------------------------------------
Enabling the Timeout OR Threshold with a value a zero is a special case.
This causes the underlying driver to poll for incoming data instead being event driven.
Otherwise, the behaviour is identical to having both the Timeout and Threshold disabled.
*/
// Following is based on my understanding of timeout parameters meaning.
// Not completely precise (threshold?!)
if(time == 0)
{ // polling mode - return if no data
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
CommTimeouts.ReadTotalTimeoutConstant = 1;
}
else if(time == -1)
{ // disable timeout
CommTimeouts.ReadIntervalTimeout = 0;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
}
else
{ // set timeout
CommTimeouts.ReadIntervalTimeout = 0;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = time;
}
// Set the time-out parameters for all read and write operations
// on the port.
if (!SetCommTimeouts (hPort, &CommTimeouts))
{ // Unable to set the time-out parameters
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, IO_EXCEPTION, L"NativeEnableReceiveTimeoutThreshold - SetCommTimeouts", lpMsgBuf);
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
return;
}
}
/*
isDTR
accept: none
perform: check status of DTR
return: true if TIOCM_DTR is set
false if TIOCM_DTR is not set
exceptions: none
comments: DTR stands for Data Terminal Ready
* Class: gnu_io_RXTXPort
* Method: isDTR
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_isDTR(JNIEnv *env, jobject jobj)
{
DCB PortDCB;
HANDLE hPort = get_fd(env, jobj);
PortDCB.DCBlength = sizeof(DCB);
// Get the default port setting information.
if(!GetCommState(hPort, &PortDCB))
{
GetLastError();
return JNI_FALSE;
}
// This is not completely correct: I assume that nobody's playing with
// manually setting/resetting DTR. Instead, DTR is in handshake mode (ON unless
// port closed) or disable mode (OFF).
// So, don't use EscapeCommFunction(SETDTR/CLRDTR) in this library!
return PortDCB.fDtrControl != DTR_CONTROL_DISABLE ? JNI_TRUE : JNI_FALSE;
}
/*
setDTR
accept: new DTR state
perform: if state is true, TIOCM_DTR is set
if state is false, TIOCM_DTR is unset
return: none
exceptions: none
comments: DTR stands for Data Terminal Ready
* Class: gnu_io_RXTXPort
* Method: setDTR
* Signature: (Z)V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_setDTR(JNIEnv *env, jobject jobj, jboolean state)
{
DCB PortDCB;
HANDLE hPort = get_fd(env, jobj);
PortDCB.DCBlength = sizeof(DCB);
// Don't use EscapeCommFunction(SETDTR/CLRDTR) in this library!
// Get the default port setting information.
if(!GetCommState (hPort, &PortDCB))
{ //Unable to get configuration of the serial port
GetLastError();
return;
}
if(state == JNI_TRUE)
PortDCB.fDtrControl = DTR_CONTROL_HANDSHAKE;
else
PortDCB.fDtrControl = DTR_CONTROL_DISABLE;
// Configure the port according to the specifications of the DCB structure.
if (!SetCommState (hPort, &PortDCB))
{ //Unable to configure the serial port
GetLastError();
return;
}
}
/*
setRTS
accept: state flag to set/unset.
perform: depends on the state flag
if true TIOCM_RTS is set
if false TIOCM_RTS is unset
return: none
exceptions: none
comments: tcsetattr with c_cflag CRTS_IFLOW
* Class: gnu_io_RXTXPort
* Method: setRTS
* Signature: (Z)V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_setRTS(JNIEnv *env, jobject jobj, jboolean state)
{
HANDLE hPort = get_fd(env, jobj);
// EscapeCommFunction will fail if there's RTS/CTS flowcontrol. If it is incorrect,
// we could turn flowcontrol off when getting to this function
if(state == JNI_TRUE)
EscapeCommFunction(hPort, SETRTS);
else
EscapeCommFunction(hPort, CLRRTS);
}
/*
setDSR
accept: state flag to set/unset.
perform: depends on the state flag
if true TIOCM_DSR is set
if false TIOCM_DSR is unset
return: none
exceptions: none
comments: tcsetattr with c_cflag CRTS_IFLOW
* Class: gnu_io_RXTXPort
* Method: setDSR
* Signature: (Z)V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_setDSR(JNIEnv *env, jobject jobj, jboolean state)
{
DCB PortDCB;
HANDLE hPort = get_fd(env, jobj);
PortDCB.DCBlength = sizeof(DCB);
// Get the default port setting information.
if(!GetCommState (hPort, &PortDCB))
{ //Unable to get configuration of the serial port
GetLastError();
return;
}
// Change the DCB structure settings.
if(state != JNI_FALSE)
PortDCB.fOutxDsrFlow = TRUE;
else
PortDCB.fOutxDsrFlow = FALSE;
// Configure the port according to the specifications of the DCB
// structure.
if (!SetCommState (hPort, &PortDCB))
{ //Unable to configure the serial port
GetLastError();
return;
}
}
/*
isCTS
accept: none
perform: check status of CTS
return: true if TIOCM_CTS is set
false if TIOCM_CTS is not set
exceptions: none
comments: CTS stands for Clear To Send.
* Class: gnu_io_RXTXPort
* Method: isCTS
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_isCTS(JNIEnv *env, jobject jobj)
{
DWORD ModemStat;
HANDLE hPort = get_fd(env, jobj);
if(!GetCommModemStatus(hPort, &ModemStat))
return JNI_FALSE;
return ModemStat|MS_CTS_ON ? JNI_TRUE : JNI_FALSE;
}
/*
isDSR
accept: none
perform: check status of DSR
return: true if TIOCM_DSR is set
false if TIOCM_DSR is not set
exceptions: none
comments: DSR stands for Data Set Ready
* Class: gnu_io_RXTXPort
* Method: isDSR
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_isDSR(JNIEnv *env, jobject jobj)
{
DWORD ModemStat;
HANDLE hPort = get_fd(env, jobj);
if(!GetCommModemStatus(hPort, &ModemStat))
return JNI_FALSE;
return ModemStat|MS_DSR_ON ? JNI_TRUE : JNI_FALSE;
}
/*
isCD
accept: none
perform: check status of CD
return: true if TIOCM_CD is set
false if TIOCM_CD is not set
exceptions: none
comments: CD stands for Carrier Detect
The following comment has been made...
"well, it works, there might ofcourse be a bug, but making DCD
permanently on fixed it for me so I don't care"
* Class: gnu_io_RXTXPort
* Method: isCD
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_isCD(JNIEnv *env, jobject jobj)
{
DWORD ModemStat;
HANDLE hPort = get_fd(env, jobj);
if(!GetCommModemStatus(hPort, &ModemStat))
return JNI_FALSE;
return ModemStat|MS_RLSD_ON ? JNI_TRUE : JNI_FALSE;
}
/*
isRI
accept: none
perform: check status of RI
return: true if TIOCM_RI is set
false if TIOCM_RI is not set
exceptions: none
comments: RI stands for Ring Indicator
* Class: gnu_io_RXTXPort
* Method: isRI
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_isRI(JNIEnv *env, jobject jobj)
{
DWORD ModemStat;
HANDLE hPort = get_fd(env, jobj);
if(!GetCommModemStatus(hPort, &ModemStat))
return JNI_FALSE;
return ModemStat|MS_RING_ON ? JNI_TRUE : JNI_FALSE;
}
/*
isRTS
accept: none
perform: check status of RTS
return: true if TIOCM_RTS is set
false if TIOCM_RTS is not set
exceptions: none
comments: tcgetattr with c_cflag CRTS_IFLOW
* Class: gnu_io_RXTXPort
* Method: isRTS
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_isRTS(JNIEnv *env, jobject jobj)
{
DCB PortDCB;
HANDLE hPort = get_fd(env, jobj);
PortDCB.DCBlength = sizeof(DCB);
if(!GetCommState (hPort, &PortDCB))
{ //Unable to get configuration of the serial port
GetLastError();
return JNI_FALSE;
}
if(PortDCB.fRtsControl == RTS_CONTROL_DISABLE)
return JNI_FALSE;
if(PortDCB.fRtsControl == RTS_CONTROL_ENABLE)
return JNI_TRUE;
if(PortDCB.fRtsControl == RTS_CONTROL_HANDSHAKE)
{
//MessageBox(NULL, L"Undefined condition: isRTS() but control is RTS_CONTROL_HANDSHAKE\r\nReturning FALSE", L"Warning", MB_OK | MB_ICONWARNING | MB_SETFOREGROUND);
printj(env, L"Undefined condition: isRTS() but control is RTS_CONTROL_HANDSHAKE. Returning FALSE\n");
return JNI_FALSE;
}
return JNI_FALSE;
}
/*
sendBreak
accept: duration in milliseconds.
perform: send break for actual time. not less than 0.25 seconds.
exceptions: none
comments: not very precise
* Class: gnu_io_RXTXPort
* Method: sendBreak
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_sendBreak(JNIEnv *env, jobject jobj, jint duration)
{
HANDLE hPort = get_fd(env, jobj);
SetCommBreak(hPort);
Sleep(duration);
ClearCommBreak(hPort);
}
/*
writeByte
accept: byte to write (passed as int)
perform: write a single byte to the port
return: none
exceptions: IOException
* Class: gnu_io_RXTXPort
* Method: writeByte
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_writeByte(JNIEnv *env, jobject jobj, jint b, jboolean i)
{
DWORD dwNumBytesWritten;
LPCWSTR lpMsgBuf;
HANDLE hPort = get_fd(env, jobj);
BYTE bb = (BYTE)b;
do {
if (!WriteFile(hPort, // Port handle
&bb, // Pointer to the data to write
1, // Number of bytes to write
&dwNumBytesWritten, // Pointer to the number of bytes written
NULL)) // Must be NULL for Windows CE
{ // WriteFile failed. Report error.
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, IO_EXCEPTION, L"writeByte - WriteFile", lpMsgBuf );
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
return;
}
} while(dwNumBytesWritten == 0);
}
/*
writeArray
accept: jbarray: bytes used for writing
off: offset in array to start writing
len: Number of bytes to write
perform: write length bytes of jbarray
return: none
exceptions: IOException
* Class: gnu_io_RXTXPort
* Method: writeArray
* Signature: ([BIIZ)V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_writeArray(JNIEnv *env, jobject jobj, jbyteArray b, jint off, jint len, jboolean i)
{
LPCWSTR lpMsgBuf;
DWORD dwNumBytesWritten;
jint total=0;
HANDLE hPort = get_fd(env, jobj);
jbyte *body = env->GetByteArrayElements(b, NULL);
do {
IF_DEBUG
(
printj(env, L"--- writeArray - %d bytes to write\n", len-total);
)
if (!WriteFile(hPort, // Port handle
body+total+off, // Pointer to the data to write
len-total, // Number of bytes to write
&dwNumBytesWritten, // Pointer to the number of bytes written
NULL)) // Must be NULL for Windows CE
{ // WriteFile failed. Report error.
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, IO_EXCEPTION, L"writeArray - WriteFile", lpMsgBuf );
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
env->ReleaseByteArrayElements(b, body, JNI_ABORT);
return;
}
total += dwNumBytesWritten;
} while( total < len );
env->ReleaseByteArrayElements(b, body, JNI_ABORT);
}
/*
nativeDrain
accept: none
perform: wait until all data is transmitted
return: none
exceptions: IOException
comments: java.io.OutputStream.flush() is equivalent to tcdrain,
not tcflush, which throws away unsent bytes
count logic added to avoid infinite loops when EINTR is
true... Thread.yeild() was suggested.
* Class: gnu_io_RXTXPort
* Method: nativeDrain
* Signature: ()V
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeDrain(JNIEnv *env, jobject jobj, jboolean i)
{
//COMSTAT Stat;
//DWORD dwErrors;
HANDLE hPort = get_fd(env, jobj);
IF_DEBUG
(
printj(env, L"--- RXTXPort.nativeDrain() called\n");
)
/*
if(!FlushFileBuffers(hPort))
{
IF_DEBUG
(
printj(env, L"!!! FlushFileBuffers() error %ld\n", GetLastError());
)
return JNI_FALSE;
}
*/
// Alternative implementation:
/*
do
{
if(!ClearCommError(hPort, &dwErrors, &Stat))
{
printj(env, L"failed RXTXPort.nativeDrain() %ld\n", GetLastError());
return JNI_FALSE;
}
Sleep(10);
} while(Stat.cbOutQue > 0);
*/
return JNI_FALSE;
}
/*
nativeavailable
accept: none
perform: find out the number of bytes available for reading
return: available bytes
-1 on error
exceptions: none /// should be IOException
* Class: gnu_io_RXTXPort
* Method: nativeavailable
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_nativeavailable(JNIEnv *env, jobject jobj)
{
DWORD dwErrors;
COMSTAT Stat;
LPCWSTR lpMsgBuf;
HANDLE hPort = get_fd(env, jobj);
IF_DEBUG
(
printj(env, L"--- RXTXPort.nativeavailable() called");
)
if(!ClearCommError(hPort, &dwErrors, &Stat))
{
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, IO_EXCEPTION, L"nativeavailable - ClearCommError", lpMsgBuf );
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
return -1;
}
IF_DEBUG
(
printj(env, L" - returning %ld\n", Stat.cbInQue);
)
return Stat.cbInQue;
}
/*
readByte
accept: none
perform: Read a single byte from the port
return: The byte read
exceptions: IOException
* Class: gnu_io_RXTXPort
* Method: readByte
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_readByte(JNIEnv *env, jobject jobj)
{
BYTE bb;
DWORD dwNumBytesRead;
LPCWSTR lpMsgBuf;
HANDLE hPort = get_fd(env, jobj);
if (!ReadFile(hPort, &bb, 1, &dwNumBytesRead, NULL))
{ // ReadFile failed. Report error.
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, IO_EXCEPTION, L"readByte - ReadFile", lpMsgBuf);
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
return -1;
}
return dwNumBytesRead > 0 ? bb : -1;
}
/*
readArray
accept: offset (offset to start storing data in the jbarray) and
Length (bytes to read)
perform: read bytes from the port into a byte array
return: bytes read on success
0 on read timeout
exceptions: IOException
comments: throws ArrayIndexOutOfBoundsException if asked to
read more than SSIZE_MAX bytes
* Class: gnu_io_RXTXPort
* Method: readArray
* Signature: ([BII)I
*/
JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_readArray(JNIEnv *env, jobject jobj, jbyteArray b, jint off, jint len)
{
LPCWSTR lpMsgBuf;
DWORD dwNumBytesRead, dwTotalRead = 0;
jint threshold;
HANDLE hPort = get_fd(env, jobj);
if(len < 0)
{
throw_java_exceptionW(env, ARRAY_INDEX_OUT_OF_BOUNDS, L"readArray", L"Negative number of character to read");
return -1;
}
jbyte *body = env->GetByteArrayElements(b, NULL);
threshold = get_java_int_var(env, jobj, "threshold");
do
{
if (!ReadFile(hPort, (unsigned char *)(body+off), len, &dwNumBytesRead, NULL))
{ // ReadFile failed. Report error.
CreateErrorMsg(GetLastError(), lpMsgBuf);
throw_java_exceptionW(env, IO_EXCEPTION, L"readArray - WriteFile", lpMsgBuf );
// Free the buffers.
ReleaseErrorMsg(lpMsgBuf);
env->ReleaseByteArrayElements(b, body, JNI_ABORT);
return -1;
}
dwTotalRead += dwNumBytesRead;
} while(dwNumBytesRead > 0 && threshold != 0 && dwTotalRead <= (DWORD)len && dwTotalRead < (DWORD)threshold);
env->ReleaseByteArrayElements(b, body, 0);
return dwTotalRead;
}
/*
eventLoop
accept: none
perform: periodically check for SerialPortEvents
return: none
exceptions: none
comments: please keep this function clean.
* Class: gnu_io_RXTXPort
* Method: eventLoop
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_eventLoop(JNIEnv *env, jobject jobj)
{
jfieldID jfMonitorThreadCloseLock, jfMonitorThreadLock, jfMonThreadisInterrupted;
jmethodID jmSendEvent;
HANDLE hCommEventThread;
DWORD dwThreadID, dwWaitResult, dwEvent;
int RetVal;
HANDLE hPort = get_fd(env, jobj);
EventInfoStruct *EventInfo = get_eis(env, jobj);
IF_DEBUG
(
printj(env, L"--- RXTXPort.eventLoop() start\n");
)
jclass cls = env->GetObjectClass(jobj);
// Get pointers to some Java variables and methods:
if( !(jfMonitorThreadLock = env->GetFieldID(cls, "MonitorThreadLock", "Z")) ||
!(jfMonThreadisInterrupted = env->GetFieldID(cls, "monThreadisInterrupted", "Z")) ||
!(jfMonitorThreadCloseLock = env->GetFieldID(cls, "MonitorThreadCloseLock", "Z")) ||
!(jmSendEvent = env->GetMethodID(cls, "sendEvent", "(IZ)Z"))
)
{
IF_DEBUG
(
env->ExceptionDescribe();
)
env->ExceptionClear();
return;
}
hCommEventThread = CreateThread(NULL, 0, CommEventThread, (LPVOID)EventInfo, 0, &dwThreadID);
if(hCommEventThread == NULL)
{
LPCWSTR lpMsgBuf;
CreateErrorMsg(GetLastError(), lpMsgBuf);
printj(env, L"!!! eventLoop - CreateThread() error: %s\n", lpMsgBuf);
ReleaseErrorMsg(lpMsgBuf);
return;
}
CloseHandle(hCommEventThread);
do
{
if(env->GetBooleanField(jobj, jfMonThreadisInterrupted) == JNI_TRUE)
{
IF_DEBUG
(
printj(env, L"--- RXTXPort.eventLoop() interrupted - exiting\n");
)
CloseHandle(EventInfo->eventHandle);
env->SetBooleanField(jobj, jfMonitorThreadCloseLock, JNI_FALSE);
return;
}
if(EventInfo->eventThreadReady)
{ // Thread is ready to work - pass signal to Java
IF_DEBUG
(
printj(env, L"--- RXTXPort.eventLoop() - EventThread is ready\n");
)
env->SetBooleanField(jobj, jfMonitorThreadLock, JNI_FALSE);
EventInfo->eventThreadReady = false;
}
if((dwWaitResult = WaitForSingleObject(EventInfo->eventHandle, 250)) == WAIT_FAILED)
{
IF_DEBUG
(
LPCWSTR lpMsgBuf;
CreateErrorMsg(GetLastError(), lpMsgBuf);
printj(env, L"!!! eventLoop - WaitForSingleObject() error: %s\n", lpMsgBuf);
ReleaseErrorMsg(lpMsgBuf);
)
CloseHandle(EventInfo->eventHandle);
env->SetBooleanField(jobj, jfMonitorThreadCloseLock, JNI_FALSE);
return;
}
if(dwWaitResult == WAIT_OBJECT_0)
{
dwEvent = EventInfo->event;
// Clearing event - event thread will continue
EventInfo->event = 0;
// Send events to Java
if(RetVal = SendEvents(env, jobj, dwEvent, EventInfo, jmSendEvent))
{
IF_DEBUG
(
printj(env, L"!!! eventLoop - SendEvents() result: %d\n", RetVal);
)
//printj(env,L"4");
CloseHandle(EventInfo->eventHandle);
env->SetBooleanField(jobj, jfMonitorThreadCloseLock, JNI_FALSE);
return;
}
}
else
{
IF_DEBUG
(
//printj(env, L"--- eventLoop() looping\n");
MessageBeep(MB_OK);
)
}
} while(TRUE);
}
/*
interruptEventLoop
accept: nothing
perform: sets monThreadisInterrupted
return: nothing
exceptions: none
comments: real monitoring thread will stay until port is closed
* Class: gnu_io_RXTXPort
* Method: interruptEventLoop
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_interruptEventLoop(JNIEnv *env, jobject jobj)
{
jfieldID jfid;
HANDLE hPort = get_fd(env, jobj);
jclass cls = env->GetObjectClass(jobj);
jfid = env->GetFieldID(cls, "monThreadisInterrupted", "Z");
env->SetBooleanField(jobj, jfid, JNI_TRUE);
}
/*
nativeSetEventFlag
accept: fd for finding the struct, event to flag, flag.
perform: toggle the flag
return: none
exceptions: none
comments: all the logic used to be done in Java but its too noisy
* Class: gnu_io_RXTXPort
* Method: nativeSetEventFlag
* Signature: (IIZ)V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_nativeSetEventFlag(JNIEnv *env, jobject jobj, jint fd, jint event, jboolean flag)
{
DWORD dwErr, NewFlag;
EventInfoStruct *EventInfo = get_eis(env, jobj);
HANDLE hPort = (HANDLE)fd;
IF_DEBUG
(
printj(env, L"--- nativeSetEventFlag(%ld, %d) called\n", event, (int)flag);
)
switch(event)
{
case SPE_DATA_AVAILABLE:
NewFlag = EV_RXCHAR;
break;
case SPE_OUTPUT_BUFFER_EMPTY:
NewFlag = EV_TXEMPTY;
break;
case SPE_CTS:
NewFlag = EV_CTS;
break;
case SPE_DSR:
NewFlag = EV_DSR;
break;
case SPE_RI:
NewFlag = EV_RING;
break;
case SPE_CD:
NewFlag = EV_RLSD;
break;
case SPE_OE:
case SPE_PE:
case SPE_FE:
NewFlag = EV_ERR;
break;
case SPE_BI:
NewFlag = EV_BREAK;
break;
}
if(flag == JNI_TRUE)
EventInfo->ef = EventInfo->ef | NewFlag;
else
EventInfo->ef = EventInfo->ef & ~NewFlag;
if(!SetCommMask(hPort, EventInfo->ef))
{
dwErr = GetLastError();
IF_DEBUG
(
LPCWSTR lpMsgBuf;
CreateErrorMsg(dwErr, lpMsgBuf);
printj(env, L"!!! nativeSetEventFlag - SetCommMask() error: %ld %s\n", dwErr, lpMsgBuf );
ReleaseErrorMsg(lpMsgBuf);
)
return;
}
}
/*
nativeClose
accept: none
perform: get the fd from the java end and close it
return: none
exceptions: none
* Class: gnu_io_RXTXPort
* Method: nativeClose
* Signature: (Ljava/lang/String{ })V
*/
JNIEXPORT void JNICALL Java_gnu_io_RXTXPort_nativeClose(JNIEnv *env, jobject jobj, jstring name)
{
HANDLE hPort = get_fd(env, jobj);
IF_DEBUG
(
LPCWSTR wszName = env->GetStringChars(name, NULL);
printj(env, L"--- RXTXPort.nativeClose(%s) called\n", wszName);
env->ReleaseStringChars(name, wszName);
)
if (!CloseHandle(hPort))
{
GetLastError();
return;
}
}
/*
nativeGetParityErrorChar
accept: -
perform: check the ParityErrorChar
return: The ParityErrorChar as an jbyte.
exceptions: UnsupportedCommOperationException if not implemented
comments: It appears the Parity char is usually \0. The windows
API allows for this to be changed. I cant find may
examples of this being done. Maybe for a reason.
Use a direct call to the termios file until we find a
solution.
* Class: gnu_io_RXTXPort
* Method: nativeGetParityErrorChar
* Signature: ()I
*/
JNIEXPORT jbyte JNICALL Java_gnu_io_RXTXPort_nativeGetParityErrorChar(JNIEnv *env, jobject jobj)
{
DCB PortDCB;
LPCWSTR lpMsgBuf;
HANDLE hPort = get_fd(env, jobj);
PortDCB.DCBlength = sizeof(DCB);
IF_DEBUG
(
printj(env, L"--- RXTXPort.nativeGetParityErrorChar() called\n");
)
// Get port setting information.
if(!GetCommState(hPort, &PortDCB))
{ //Unable to get configuration of the serial port
CreateErrorMsg(GetLastError(), lpMsgBuf);
IF_DEBUG
(
printj(env, L"!!! nativeGetParityErrorChar - GetCommState() error: %s\n", lpMsgBuf);
)
ReleaseErrorMsg(lpMsgBuf);
return -1;
}
return (jbyte)PortDCB.ErrorChar;
}
/*
nativeSetParityErrorChar
accept: the ParityArrorCharacter as an int.
perform: Set the ParityErrorChar
return: JNI_TRUE on success
exceptions: UnsupportedCommOperationException if not implemented
comments: It appears the Parity char is usually \0. The windows
API allows for this to be changed. I cant find may
examples of this being done. Maybe for a reason.
Use a direct call to the termios file until we find a
solution.
* Class: gnu_io_RXTXPort
* Method: nativeSetParityErrorChar
* Signature: (B)Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetParityErrorChar(JNIEnv *env, jobject jobj, jbyte b)
{
DCB PortDCB;
LPCWSTR lpMsgBuf;
HANDLE hPort = get_fd(env, jobj);
PortDCB.DCBlength = sizeof(DCB);
IF_DEBUG
(
printj(env, L"--- RXTXPort.nativeSetParityErrorChar(%#x) called\n", (int)b);
)
// Get port setting information.
if(!GetCommState(hPort, &PortDCB))
{ //Unable to get configuration of the serial port
CreateErrorMsg(GetLastError(), lpMsgBuf);
IF_DEBUG
(
printj(env, L"!!! nativeSetParityErrorChar - GetCommState() error: %s\n", lpMsgBuf);
)
ReleaseErrorMsg(lpMsgBuf);
return JNI_FALSE;
}
if(b != 0)
{
PortDCB.fErrorChar = TRUE;
PortDCB.fParity = TRUE;
PortDCB.ErrorChar = b;
}
else
{
PortDCB.fErrorChar = FALSE;
PortDCB.fParity = FALSE;
PortDCB.ErrorChar = 0;
}
if (!SetCommState(hPort, &PortDCB))
{
CreateErrorMsg(GetLastError(), lpMsgBuf);
IF_DEBUG
(
printj(env, L"!!! nativeSetParityErrorChar - SetCommState() error: %s\n", lpMsgBuf);
)
ReleaseErrorMsg(lpMsgBuf);
return JNI_FALSE;
}
return JNI_TRUE;
}
/*
nativeGetEndOfInputChar
accept: -
perform: check the EndOf InputChar
return: the EndOfInputChar as an jbyte. -1 on error
exceptions: UnsupportedCommOperationException if not implemented
comments:
* Class: gnu_io_RXTXPort
* Method: nativeGetEndOfInputChar
* Signature: ()I
*/
JNIEXPORT jbyte JNICALL Java_gnu_io_RXTXPort_nativeGetEndOfInputChar(JNIEnv *env, jobject jobj)
{
DCB PortDCB;
LPCWSTR lpMsgBuf;
HANDLE hPort = get_fd(env, jobj);
PortDCB.DCBlength = sizeof(DCB);
IF_DEBUG
(
printj(env, L"--- RXTXPort.nativeGetEndOfInputChar() called\n");
)
// Get port setting information.
if(!GetCommState(hPort, &PortDCB))
{ //Unable to get configuration of the serial port
CreateErrorMsg(GetLastError(), lpMsgBuf);
IF_DEBUG
(
printj(env, L"!!! nativeGetEndOfInputChar - GetCommState() error: %s\n", lpMsgBuf);
)
ReleaseErrorMsg(lpMsgBuf);
return -1;
}
return (jbyte)PortDCB.EofChar;
}
/*
nativeSetEndOfInputChar
accept: The EndOfInputChar as an int
perform: set the EndOfInputChar
return: JNI_TRUE on success
exceptions: UnsupportedCommOperationException if not implemented
comments: This may cause troubles on Windows.
Lets give it a shot and see what happens.
See termios.c for the windows bits.
EofChar = val;
fBinary = false; //winapi docs say always use true. ?
* Class: gnu_io_RXTXPort
* Method: nativeSetEndOfInputChar
* Signature: (B)Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetEndOfInputChar(JNIEnv *env, jobject jobj, jbyte b)
{
DCB PortDCB;
LPCWSTR lpMsgBuf;
HANDLE hPort = get_fd(env, jobj);
PortDCB.DCBlength = sizeof(DCB);
IF_DEBUG
(
printj(env, L"--- RXTXPort.nativeSetEndOfInputChar(%#x) called\n", (int)b);
)
// Get port setting information.
if(!GetCommState(hPort, &PortDCB))
{ //Unable to get configuration of the serial port
CreateErrorMsg(GetLastError(), lpMsgBuf);
IF_DEBUG
(
printj(env, L"!!! nativeSetEndOfInputChar - GetCommState() error: %s\n", lpMsgBuf);
)
ReleaseErrorMsg(lpMsgBuf);
return JNI_FALSE;
}
if( b != 0)
{
PortDCB.fBinary = FALSE;
PortDCB.EofChar = b;
}
else
{
PortDCB.fBinary = TRUE;
PortDCB.EofChar = 0;
}
if (!SetCommState(hPort, &PortDCB))
{
CreateErrorMsg(GetLastError(), lpMsgBuf);
IF_DEBUG
(
printj(env, L"!!! nativeSetEndOfInputChar - SetCommState() error: %s\n", lpMsgBuf);
)
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetEndOfInputChar", lpMsgBuf);
ReleaseErrorMsg(lpMsgBuf);
return JNI_FALSE;
}
return JNI_TRUE;
}
/*
* Class: gnu_io_RXTXPort
* Method: nativeSetUartType
* Signature: (Ljava/lang/String{ }Z)Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetUartType(JNIEnv *env, jobject jobj, jstring type, jboolean test)
{
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetUartType", L"Operation not implemented");
return JNI_FALSE;
}
/*
* Class: gnu_io_RXTXPort
* Method: nativeGetUartType
* Signature: ()Ljava/lang/String{ }
*/
JNIEXPORT jstring JNICALL Java_gnu_io_RXTXPort_nativeGetUartType(JNIEnv *env, jobject jobj)
{
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetUartType", L"Operation not implemented");
return env->NewStringUTF("Unknown");
}
/*
* Class: gnu_io_RXTXPort
* Method: nativeSetBaudBase
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetBaudBase(JNIEnv *env, jobject jobj, jint baudBase)
{
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetBaudBase", L"Operation not implemented");
return JNI_FALSE;
}
/*
* Class: gnu_io_RXTXPort
* Method: nativeGetBaudBase
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_nativeGetBaudBase(JNIEnv *env, jobject jobj)
{
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeGetBaudBase", L"Operation not implemented");
return -1;
}
/*
* Class: gnu_io_RXTXPort
* Method: nativeSetDivisor
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetDivisor(JNIEnv *env, jobject jobj, jint divisor)
{
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetDivisor", L"Operation not implemented");
return JNI_FALSE;
}
/*
* Class: gnu_io_RXTXPort
* Method: nativeGetDivisor
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_gnu_io_RXTXPort_nativeGetDivisor(JNIEnv *env, jobject jobj)
{
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeGetDivisor", L"Operation not implemented");
return -1;
}
/*
* Class: gnu_io_RXTXPort
* Method: nativeSetLowLatency
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetLowLatency(JNIEnv *env, jobject jobj)
{
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetLowLatency", L"Operation not implemented");
return JNI_FALSE;
}
/*
* Class: gnu_io_RXTXPort
* Method: nativeGetLowLatency
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeGetLowLatency(JNIEnv *env, jobject jobj)
{
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeGetLowLatency", L"Operation not implemented");
return JNI_FALSE;
}
/*
* Class: gnu_io_RXTXPort
* Method: nativeSetCallOutHangup
* Signature: (Z)Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeSetCallOutHangup(JNIEnv *env, jobject jobj, jboolean noHup)
{
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeSetCallOutHangup", L"Operation not implemented");
return JNI_FALSE;
}
/*
* Class: gnu_io_RXTXPort
* Method: nativeGetCallOutHangup
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_gnu_io_RXTXPort_nativeGetCallOutHangup(JNIEnv *env, jobject jobj)
{
throw_java_exceptionW(env, UNSUPPORTED_COMM_OPERATION, L"nativeGetCallOutHangup", L"Operation not implemented");
return JNI_FALSE;
}