pax_global_header 0000666 0000000 0000000 00000000064 12270474732 0014522 g ustar 00root root 0000000 0000000 52 comment=f5564869f8a70503c29c0d24609245321ba39b2c
java-simple-serial-connector-2.8.0/ 0000775 0000000 0000000 00000000000 12270474732 0017206 5 ustar 00root root 0000000 0000000 java-simple-serial-connector-2.8.0/README.txt 0000664 0000000 0000000 00000017213 12270474732 0020710 0 ustar 00root root 0000000 0000000 jSSC-2.8.0 Release version (24.01.2014)
This version contains native libs for Windows(x86, x86-64), Linux(x86, x86-64, ARM soft & hard float), Solaris(x86, x86-64), Mac OS X(x86, x86-64, PPC, PPC64).
All native libs contains in the jssc.jar file and you don't need manage native libs manually.
In this build:
Fixes:
* Important! Fixed bug with port handles potential leakage
Additions:
* Added method "writeString(String string, String charsetName)"
* Added method "getNativeLibraryVersion" in "SerialNativeInterface" class
* Enabled Java and Native libraries versions mismatch check
With Best Regards, Sokolov Alexey aka scream3r.
============= Previous Builds ==============
///////////////////////////////////////////
//jSSC-2.6.0 Release version (01.06.2013)//
///////////////////////////////////////////
In this build:
Note: Linux x86 and x86-64 was builded on Ubuntu 10.04 and don't depends GLIBC-2.15 unlike jSSC-2.5.0
Additions:
* Added os.name - "Darwin" and os.arch - "universal" support. It can be useful for MacOS X developers.
* Added ttyO to Linux RegExp for listing OMAP serial devices.
* Added JSSC_IGNPAR and JSSC_PARMRK properties for enabling IGNPAR and PARMRK flags in _nix termios structure.
///////////////////////////////////////////
//jSSC-2.5.0 Release version (27.04.2013)//
///////////////////////////////////////////
In this build:
Fixes:
* Important! Fixed bug with garbage reading on Linux, MacOSX, Solaris, cause of incorrect using of VMIN and VTIME. Now "read" methods works correctly and are blocking like in Windows
* Important! Fixed error with garbage reading in Windows using jSSC after another application used serial port. To prevent this effect COMMTIMEOUTS structure zeroing added to setParams() method
* Important! The port handle now stored in variable of type "long" instead of "int", to prevent potential problems with type conversions on Win64
* Fixed MacOS X 10.8 bug with native lib loading (*.dylib -> *.jnilib)
* Fixed Linux error with exclusive access to serial port (TIOCEXCL). TIOCNXCL added to closePort() method for clearing exclusive access
* Fixed Windows native lib port name concatenation error
* Fixed native lib extraction path if user home is read only, in this situation lib will be extracted to tmp folder
* Null port name fix. If try to invoke method openPort() for SerialPort(null) object, exception TYPE_NULL_NOT_PERMITTED will be thrown
* Enabled TIOCEXCL support in Solaris
Additions:
* Added ARM Soft & Hard float support (Tested of Raspberry Pi with Oracle JDK(6-7-8))
* Added ttyACM, ttyAMA, rfcomm to Linux RegExp and tty.usbmodem to MacOS X RegExp
* Added precompiled RegExp's for Linux, Solaris, MacOS X for more faster port listing
* Added private common for Linux, Solaris, MacOS X method getUnixBasedPortNames() for listing serial ports
* Rewrited comparator for sorting port names. Now it's a common comparator for Windows, Linux, Solaris and MacOS X
* Added some syntax sugar to SerialPortList class, for changing search path, RegExp and comparator
* Added timeouts for read operations and SerialPortTimeoutException class for catching timeout exceptions
* Added JSSC_NO_TIOCEXCL JVM property for disable using of exclusive access to serial port
* Added termios(_nix) and DCB(Windows) structure cheking on port opening, it helps separate real serial devices from others
* Added "ERR_" constants into SerialNativeInterface
* Added new exception TYPE_INCORRECT_SERIAL_PORT
* Added new exception TYPE_PERMISSION_DENIED. It can be very useful for _nix based system if user have no permissions for using serial device
And other little modifications...
///////////////////////////////////////////
//jSSC-0.9.0 Release version (21.12.2011)//
///////////////////////////////////////////
In this build:
* Added Solaris support (x86, x86-64)
* Added Mac OS X support 10.5 and higher(x86, x86-64, PPC, PPC64)
* Fixed some bugs in Linux native part
* Changed openPort() method
Important Note:
openPort() method has been changed, now if port busy SerialPortException with type: TYPE_PORT_BUSY will be thrown,
and if port not found SerialPortException with type: TYPE_PORT_NOT_FOUND will be thrown.
It's possible to know that port is busy (TYPE_PORT_BUSY) by using TIOCEXCL directive in *nix native library,
but using of this directive make some troubles in Solaris OS, that's why TIOCEXCL not used in Solaris (!)
Be careful with it.
Also Solaris and Mac OS X versions of jSSC not support following events:
ERR, TXEMPTY, BREAK.
Solaris version not support non standard baudrates
Mac OS X version not support parity: MARK, SPACE.
* Included javadoc and source codes
/////////////////////////////////////////
//jSSC-0.8 Release version (28.11.2011)//
/////////////////////////////////////////
In this build:
* Implemented events BREAK and ERR (RXFLAG not supported in Linux)
* Added method sendBreak(int duration) - send Break signal for setted time
* Fixed bugs in Linux events listener
* Fixed bug with long port closing operation in Linux
/////////////////////////////
//jSSC-0.8-tb4 (21.11.2011)//
/////////////////////////////
In this build was fixed a bug in getPortNames() method under Linux.
Not implemented yet list:
* Events: BREAK, ERR and RXFLAG
/////////////////////////////
//jSSC-0.8-tb3 (09.09.2011)//
/////////////////////////////
In this build was implemented:
* purgePort()
And was fixed some Linux and Windows lib bugs.
New in this build:
* getInputBufferBytesCount() - get count of bytes in input buffer (if error has occured -1 will be returned)
* getOutputBufferBytesCount() - get count of bytes in output buffer (if error has occured -1 will be returned)
* setFlowControlMode() - setting flow control (available: FLOWCONTROL_NONE,
FLOWCONTROL_RTSCTS_IN,
FLOWCONTROL_RTSCTS_OUT,
FLOWCONTROL_XONXOFF_IN,
FLOWCONTROL_XONXOFF_OUT)
* getFlowControlMode() - getting setted flow control mode
Some "syntactic sugar" for more usability:
* writeByte() - write single byte
* writeString() - write string
* writeInt() - write int value (for example 0xFF)
* writeIntArray - write int array (for example new int[]{0xFF, 0x00, 0xFF})
* readString(int byteCount) - read string
* readHexString(int byteCount) - read Hex string with a space separator (for example "FF 00 FF")
* readHexString(int byteCount, String separator) - read Hex string with setted separator (for example if separator : "FF:00:FF")
* readHexStringArray(int byteCount) - read Hex string array (for example {FF, 00, FF})
* readIntArray(int byteCount) - read int array (values in int array are in range from 0 to 255
for example if byte == -1 value in this array it will be 255)
The following methods read all bytes in input buffer, if buffer is empty methods will return null
* readBytes()
* readString()
* readHexString()
* readHexString()
* readHexStringArray()
* readIntArray()
============================================
Not implemented yet list:
* Events: BREAK, ERR and RXFLAG
///////////////////////////////
// jSSC-0.8-tb2 (14.07.2011) //
///////////////////////////////
In this build was implemented:
* getPortNames()
* Parity: MARK and SPACE
And was fixed some Linux lib bugs.
Not implemented yet list:
* purgePort()
* Events: BREAK, ERR and RXFLAG
///////////////////////////////
// jSSC-0.8-tb1 (11.07.2011) //
///////////////////////////////
Not implemented yet list:
* getPortNames()
* Parity: MARK and SPACE
* purgePort()
* Events: BREAK, ERR and RXFLAG
java-simple-serial-connector-2.8.0/src/ 0000775 0000000 0000000 00000000000 12270474732 0017775 5 ustar 00root root 0000000 0000000 java-simple-serial-connector-2.8.0/src/cpp/ 0000775 0000000 0000000 00000000000 12270474732 0020557 5 ustar 00root root 0000000 0000000 java-simple-serial-connector-2.8.0/src/cpp/_nix_based/ 0000775 0000000 0000000 00000000000 12270474732 0022652 5 ustar 00root root 0000000 0000000 java-simple-serial-connector-2.8.0/src/cpp/_nix_based/jssc.cpp 0000664 0000000 0000000 00000061521 12270474732 0024325 0 ustar 00root root 0000000 0000000 /* jSSC (Java Simple Serial Connector) - serial port communication library.
* © Alexey Sokolov (scream3r), 2010-2014.
*
* This file is part of jSSC.
*
* jSSC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jSSC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with jSSC. If not, see .
*
* If you use jSSC in public project you can inform me about this by e-mail,
* of course if you want it.
*
* e-mail: scream3r.org@gmail.com
* web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/
*/
#include
#include
#include
#include
#include
#include
#include //-D_TS_ERRNO use for Solaris C++ compiler
#include //since 2.5.0
#ifdef __linux__
#include
#endif
#ifdef __SunOS
#include //Needed for FIONREAD in Solaris
#include //Needed for select() function
#endif
#ifdef __APPLE__
#include //Needed for IOSSIOSPEED in Mac OS X (Non standard baudrate)
#endif
#include
#include "../jssc_SerialNativeInterface.h"
//#include //-lCstd use for Solaris linker
/*
* Get native library version
*/
JNIEXPORT jstring JNICALL Java_jssc_SerialNativeInterface_getNativeLibraryVersion(JNIEnv *env, jobject object) {
return env->NewStringUTF(jSSC_NATIVE_LIB_VERSION);
}
/* OK */
/*
* Port opening
*
* In 2.2.0 added useTIOCEXCL
*/
JNIEXPORT jlong JNICALL Java_jssc_SerialNativeInterface_openPort(JNIEnv *env, jobject object, jstring portName, jboolean useTIOCEXCL){
const char* port = env->GetStringUTFChars(portName, JNI_FALSE);
jlong hComm = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
if(hComm != -1){
//since 2.2.0 -> (check termios structure for separating real serial devices from others)
termios *settings = new termios();
if(tcgetattr(hComm, settings) == 0){
#if defined TIOCEXCL //&& !defined __SunOS
if(useTIOCEXCL == JNI_TRUE){
ioctl(hComm, TIOCEXCL);
}
#endif
int flags = fcntl(hComm, F_GETFL, 0);
flags &= ~O_NDELAY;
fcntl(hComm, F_SETFL, flags);
}
else {
close(hComm);//since 2.7.0
hComm = jssc_SerialNativeInterface_ERR_INCORRECT_SERIAL_PORT;//-4;
}
delete settings;
//<- since 2.2.0
}
else {//since 0.9 ->
if(errno == EBUSY){//Port busy
hComm = jssc_SerialNativeInterface_ERR_PORT_BUSY;//-1
}
else if(errno == ENOENT){//Port not found
hComm = jssc_SerialNativeInterface_ERR_PORT_NOT_FOUND;//-2;
}//-> since 2.2.0
else if(errno == EACCES){//Permission denied
hComm = jssc_SerialNativeInterface_ERR_PERMISSION_DENIED;//-3;
}
else {
hComm = jssc_SerialNativeInterface_ERR_PORT_NOT_FOUND;//-2;
}//<- since 2.2.0
}//<- since 0.9
env->ReleaseStringUTFChars(portName, port);
return hComm;
}
/* OK */
/*
* Choose baudrate
*/
speed_t getBaudRateByNum(jint baudRate) {
switch(baudRate){
case 0:
return B0;
case 50:
return B50;
case 75:
return B75;
case 110:
return B110;
case 134:
return B134;
case 150:
return B150;
case 200:
return B200;
case 300:
return B300;
case 600:
return B600;
case 1200:
return B1200;
case 1800:
return B1800;
case 2400:
return B2400;
case 4800:
return B4800;
case 9600:
return B9600;
case 19200:
return B19200;
case 38400:
return B38400;
#ifdef B57600
case 57600:
return B57600;
#endif
#ifdef B115200
case 115200:
return B115200;
#endif
#ifdef B230400
case 230400:
return B230400;
#endif
#ifdef B460800
case 460800:
return B460800;
#endif
#ifdef B500000
case 500000:
return B500000;
#endif
#ifdef B576000
case 576000:
return B576000;
#endif
#ifdef B921600
case 921600:
return B921600;
#endif
#ifdef B1000000
case 1000000:
return B1000000;
#endif
#ifdef B1152000
case 1152000:
return B1152000;
#endif
#ifdef B1500000
case 1500000:
return B1500000;
#endif
#ifdef B2000000
case 2000000:
return B2000000;
#endif
#ifdef B2500000
case 2500000:
return B2500000;
#endif
#ifdef B3000000
case 3000000:
return B3000000;
#endif
#ifdef B3500000
case 3500000:
return B3500000;
#endif
#ifdef B4000000
case 4000000:
return B4000000;
#endif
default:
return -1;
}
}
/* OK */
/*
* Choose data bits
*/
int getDataBitsByNum(jint byteSize) {
switch(byteSize){
case 5:
return CS5;
case 6:
return CS6;
case 7:
return CS7;
case 8:
return CS8;
default:
return -1;
}
}
//since 2.6.0 ->
const jint PARAMS_FLAG_IGNPAR = 1;
const jint PARAMS_FLAG_PARMRK = 2;
//<- since 2.6.0
/* OK */
/*
* Set serial port settings
*
* In 2.6.0 added flags parameter
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setParams
(JNIEnv *env, jobject object, jlong portHandle, jint baudRate, jint byteSize, jint stopBits, jint parity, jboolean setRTS, jboolean setDTR, jint flags){
jboolean returnValue = JNI_FALSE;
speed_t baudRateValue = getBaudRateByNum(baudRate);
int dataBits = getDataBitsByNum(byteSize);
termios *settings = new termios();
if(tcgetattr(portHandle, settings) == 0){
if(baudRateValue != -1){
//Set standart baudrate from "termios.h"
if(cfsetispeed(settings, baudRateValue) < 0 || cfsetospeed(settings, baudRateValue) < 0){
goto methodEnd;
}
}
else {
#ifdef __SunOS
goto methodEnd;//Solaris don't support non standart baudrates
#elif defined __linux__
//Try to calculate a divisor for setting non standart baudrate
serial_struct *serial_info = new serial_struct();
if(ioctl(portHandle, TIOCGSERIAL, serial_info) < 0){ //Getting serial_info structure
delete serial_info;
goto methodEnd;
}
else {
serial_info->flags |= ASYNC_SPD_CUST;
serial_info->custom_divisor = (serial_info->baud_base/baudRate); //Calculate divisor
if(serial_info->custom_divisor == 0){ //If divisor == 0 go to method end to prevent "division by zero" error
delete serial_info;
goto methodEnd;
}
settings->c_cflag |= B38400;
if(cfsetispeed(settings, B38400) < 0 || cfsetospeed(settings, B38400) < 0){
delete serial_info;
goto methodEnd;
}
if(ioctl(portHandle, TIOCSSERIAL, serial_info) < 0){//Try to set new settings with non standart baudrate
delete serial_info;
goto methodEnd;
}
delete serial_info;
}
#endif
}
}
/*
* Setting data bits
*/
if(dataBits != -1){
settings->c_cflag &= ~CSIZE;
settings->c_cflag |= dataBits;
}
else {
goto methodEnd;
}
/*
* Setting stop bits
*/
if(stopBits == 0){ //1 stop bit (for info see ->> MSDN)
settings->c_cflag &= ~CSTOPB;
}
else if((stopBits == 1) || (stopBits == 2)){ //1 == 1.5 stop bits; 2 == 2 stop bits (for info see ->> MSDN)
settings->c_cflag |= CSTOPB;
}
else {
goto methodEnd;
}
settings->c_cflag |= (CREAD | CLOCAL);
settings->c_cflag &= ~CRTSCTS;
settings->c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOCTL | ECHOPRT | ECHOKE | ISIG | IEXTEN);
settings->c_iflag &= ~(IXON | IXOFF | IXANY | INPCK | IGNPAR | PARMRK | ISTRIP | IGNBRK | BRKINT | INLCR | IGNCR| ICRNL);
#ifdef IUCLC
settings->c_iflag &= ~IUCLC;
#endif
settings->c_oflag &= ~OPOST;
//since 2.6.0 ->
if((flags & PARAMS_FLAG_IGNPAR) == PARAMS_FLAG_IGNPAR){
settings->c_iflag |= IGNPAR;
}
if((flags & PARAMS_FLAG_PARMRK) == PARAMS_FLAG_PARMRK){
settings->c_iflag |= PARMRK;
}
//<- since 2.6.0
//since 0.9 ->
settings->c_cc[VMIN] = 0;
settings->c_cc[VTIME] = 0;
//<- since 0.9
/*
* Parity bits
*/
#ifdef PAREXT
settings->c_cflag &= ~(PARENB | PARODD | PAREXT);//Clear parity settings
#elif defined CMSPAR
settings->c_cflag &= ~(PARENB | PARODD | CMSPAR);//Clear parity settings
#else
settings->c_cflag &= ~(PARENB | PARODD);//Clear parity settings
#endif
if(parity == 1){//Parity ODD
settings->c_cflag |= (PARENB | PARODD);
settings->c_iflag |= INPCK;
}
else if(parity == 2){//Parity EVEN
settings->c_cflag |= PARENB;
settings->c_iflag |= INPCK;
}
else if(parity == 3){//Parity MARK
#ifdef PAREXT
settings->c_cflag |= (PARENB | PARODD | PAREXT);
settings->c_iflag |= INPCK;
#elif defined CMSPAR
settings->c_cflag |= (PARENB | PARODD | CMSPAR);
settings->c_iflag |= INPCK;
#endif
}
else if(parity == 4){//Parity SPACE
#ifdef PAREXT
settings->c_cflag |= (PARENB | PAREXT);
settings->c_iflag |= INPCK;
#elif defined CMSPAR
settings->c_cflag |= (PARENB | CMSPAR);
settings->c_iflag |= INPCK;
#endif
}
else if(parity == 0){
//Do nothing (Parity NONE)
}
else {
goto methodEnd;
}
if(tcsetattr(portHandle, TCSANOW, settings) == 0){//Try to set all settings
#ifdef __APPLE__
//Try to set non-standard baud rate in Mac OS X
if(baudRateValue == -1){
speed_t speed = (speed_t)baudRate;
if(ioctl(portHandle, IOSSIOSPEED, &speed) < 0){//IOSSIOSPEED must be used only after tcsetattr
goto methodEnd;
}
}
#endif
int lineStatus;
if(ioctl(portHandle, TIOCMGET, &lineStatus) >= 0){
if(setRTS == JNI_TRUE){
lineStatus |= TIOCM_RTS;
}
else {
lineStatus &= ~TIOCM_RTS;
}
if(setDTR == JNI_TRUE){
lineStatus |= TIOCM_DTR;
}
else {
lineStatus &= ~TIOCM_DTR;
}
if(ioctl(portHandle, TIOCMSET, &lineStatus) >= 0){
returnValue = JNI_TRUE;
}
}
}
methodEnd: {
delete settings;
return returnValue;
}
}
const jint PURGE_RXABORT = 0x0002; //ignored
const jint PURGE_RXCLEAR = 0x0008;
const jint PURGE_TXABORT = 0x0001; //ignored
const jint PURGE_TXCLEAR = 0x0004;
/* OK */
/*
* PurgeComm
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_purgePort
(JNIEnv *env, jobject object, jlong portHandle, jint flags){
int clearValue = -1;
if((flags & PURGE_RXCLEAR) && (flags & PURGE_TXCLEAR)){
clearValue = TCIOFLUSH;
}
else if(flags & PURGE_RXCLEAR) {
clearValue = TCIFLUSH;
}
else if(flags & PURGE_TXCLEAR) {
clearValue = TCOFLUSH;
}
else if((flags & PURGE_RXABORT) || (flags & PURGE_TXABORT)){
return JNI_TRUE;
}
else {
return JNI_FALSE;
}
return tcflush(portHandle, clearValue) == 0 ? JNI_TRUE : JNI_FALSE;
}
/* OK */
/* Closing the port */
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_closePort
(JNIEnv *env, jobject object, jlong portHandle){
#if defined TIOCNXCL //&& !defined __SunOS
ioctl(portHandle, TIOCNXCL);//since 2.1.0 Clear exclusive port access on closing
#endif
return close(portHandle) == 0 ? JNI_TRUE : JNI_FALSE;
}
/* OK */
/*
* Setting events mask
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setEventsMask
(JNIEnv *env, jobject object, jlong portHandle, jint mask){
//Don't needed in linux, implemented in java code
return JNI_TRUE;
}
/* OK */
/*
* Getting events mask
*/
JNIEXPORT jint JNICALL Java_jssc_SerialNativeInterface_getEventsMask
(JNIEnv *env, jobject object, jlong portHandle){
//Don't needed in linux, implemented in java code
return -1;
}
/* OK */
/*
* RTS line status changing (ON || OFF)
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setRTS
(JNIEnv *env, jobject object, jlong portHandle, jboolean enabled){
int returnValue = 0;
int lineStatus;
ioctl(portHandle, TIOCMGET, &lineStatus);
if(enabled == JNI_TRUE){
lineStatus |= TIOCM_RTS;
}
else {
lineStatus &= ~TIOCM_RTS;
}
returnValue = ioctl(portHandle, TIOCMSET, &lineStatus);
return (returnValue >= 0 ? JNI_TRUE : JNI_FALSE);
}
/* OK */
/*
* DTR line status changing (ON || OFF)
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setDTR
(JNIEnv *env, jobject object, jlong portHandle, jboolean enabled){
int returnValue = 0;
int lineStatus;
ioctl(portHandle, TIOCMGET, &lineStatus);
if(enabled == JNI_TRUE){
lineStatus |= TIOCM_DTR;
}
else {
lineStatus &= ~TIOCM_DTR;
}
returnValue = ioctl(portHandle, TIOCMSET, &lineStatus);
return (returnValue >= 0 ? JNI_TRUE : JNI_FALSE);
}
/* OK */
/*
* Writing data to the port
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes
(JNIEnv *env, jobject object, jlong portHandle, jbyteArray buffer){
jbyte* jBuffer = env->GetByteArrayElements(buffer, JNI_FALSE);
jint bufferSize = env->GetArrayLength(buffer);
jint result = write(portHandle, jBuffer, (size_t)bufferSize);
env->ReleaseByteArrayElements(buffer, jBuffer, 0);
return result == bufferSize ? JNI_TRUE : JNI_FALSE;
}
/* OK */
/*
* Reading data from the port
*
* Rewrited in 2.5.0 (using select() function for correct block reading in MacOS X)
*/
JNIEXPORT jbyteArray JNICALL Java_jssc_SerialNativeInterface_readBytes
(JNIEnv *env, jobject object, jlong portHandle, jint byteCount){
fd_set read_fd_set;
jbyte *lpBuffer = new jbyte[byteCount];
int byteRemains = byteCount;
while(byteRemains > 0) {
FD_ZERO(&read_fd_set);
FD_SET(portHandle, &read_fd_set);
select(portHandle + 1, &read_fd_set, NULL, NULL, NULL);
int result = read(portHandle, lpBuffer + (byteCount - byteRemains), byteRemains);
if(result > 0){
byteRemains -= result;
}
}
FD_CLR(portHandle, &read_fd_set);
jbyteArray returnArray = env->NewByteArray(byteCount);
env->SetByteArrayRegion(returnArray, 0, byteCount, lpBuffer);
delete lpBuffer;
return returnArray;
}
/* OK */
/*
* Get bytes count in serial port buffers (Input and Output)
*/
JNIEXPORT jintArray JNICALL Java_jssc_SerialNativeInterface_getBuffersBytesCount
(JNIEnv *env, jobject object, jlong portHandle){
jint returnValues[2];
returnValues[0] = -1; //Input buffer
returnValues[1] = -1; //Output buffer
jintArray returnArray = env->NewIntArray(2);
ioctl(portHandle, FIONREAD, &returnValues[0]);
ioctl(portHandle, TIOCOUTQ, &returnValues[1]);
env->SetIntArrayRegion(returnArray, 0, 2, returnValues);
return returnArray;
}
const jint FLOWCONTROL_NONE = 0;
const jint FLOWCONTROL_RTSCTS_IN = 1;
const jint FLOWCONTROL_RTSCTS_OUT = 2;
const jint FLOWCONTROL_XONXOFF_IN = 4;
const jint FLOWCONTROL_XONXOFF_OUT = 8;
/* OK */
/*
* Setting flow control mode
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setFlowControlMode
(JNIEnv *env, jobject object, jlong portHandle, jint mask){
jboolean returnValue = JNI_FALSE;
termios *settings = new termios();
if(tcgetattr(portHandle, settings) == 0){
settings->c_cflag &= ~CRTSCTS;
settings->c_iflag &= ~(IXON | IXOFF);
if(mask != FLOWCONTROL_NONE){
if(((mask & FLOWCONTROL_RTSCTS_IN) == FLOWCONTROL_RTSCTS_IN) || ((mask & FLOWCONTROL_RTSCTS_OUT) == FLOWCONTROL_RTSCTS_OUT)){
settings->c_cflag |= CRTSCTS;
}
if((mask & FLOWCONTROL_XONXOFF_IN) == FLOWCONTROL_XONXOFF_IN){
settings->c_iflag |= IXOFF;
}
if((mask & FLOWCONTROL_XONXOFF_OUT) == FLOWCONTROL_XONXOFF_OUT){
settings->c_iflag |= IXON;
}
}
if(tcsetattr(portHandle, TCSANOW, settings) == 0){
returnValue = JNI_TRUE;
}
}
delete settings;
return returnValue;
}
/* OK */
/*
* Getting flow control mode
*/
JNIEXPORT jint JNICALL Java_jssc_SerialNativeInterface_getFlowControlMode
(JNIEnv *env, jobject object, jlong portHandle){
jint returnValue = 0;
termios *settings = new termios();
if(tcgetattr(portHandle, settings) == 0){
if(settings->c_cflag & CRTSCTS){
returnValue |= (FLOWCONTROL_RTSCTS_IN | FLOWCONTROL_RTSCTS_OUT);
}
if(settings->c_iflag & IXOFF){
returnValue |= FLOWCONTROL_XONXOFF_IN;
}
if(settings->c_iflag & IXON){
returnValue |= FLOWCONTROL_XONXOFF_OUT;
}
}
return returnValue;
}
/* OK */
/*
* Send break for setted duration
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_sendBreak
(JNIEnv *env, jobject object, jlong portHandle, jint duration){
jboolean returnValue = JNI_FALSE;
if(duration > 0){
if(ioctl(portHandle, TIOCSBRK, 0) >= 0){
int sec = (duration >= 1000 ? duration/1000 : 0);
int nanoSec = (sec > 0 ? duration - sec*1000 : duration)*1000000;
struct timespec *timeStruct = new timespec();
timeStruct->tv_sec = sec;
timeStruct->tv_nsec = nanoSec;
nanosleep(timeStruct, NULL);
delete(timeStruct);
if(ioctl(portHandle, TIOCCBRK, 0) >= 0){
returnValue = JNI_TRUE;
}
}
}
return returnValue;
}
/* OK */
/*
* Return "statusLines" from ioctl(portHandle, TIOCMGET, &statusLines)
* Need for "_waitEvents" and "_getLinesStatus"
*/
int getLinesStatus(jlong portHandle) {
int statusLines;
ioctl(portHandle, TIOCMGET, &statusLines);
return statusLines;
}
/* OK */
/*
* Not supported in Solaris and Mac OS X
*
* Get interrupts count for:
* 0 - Break(for BREAK event)
* 1 - TX(for TXEMPTY event)
* --ERRORS(for ERR event)--
* 2 - Frame
* 3 - Overrun
* 4 - Parity
*/
void getInterruptsCount(jlong portHandle, int intArray[]) {
#ifdef TIOCGICOUNT
struct serial_icounter_struct *icount = new serial_icounter_struct();
if(ioctl(portHandle, TIOCGICOUNT, icount) >= 0){
intArray[0] = icount->brk;
intArray[1] = icount->tx;
intArray[2] = icount->frame;
intArray[3] = icount->overrun;
intArray[4] = icount->parity;
}
delete icount;
#endif
}
const jint INTERRUPT_BREAK = 512;
const jint INTERRUPT_TX = 1024;
const jint INTERRUPT_FRAME = 2048;
const jint INTERRUPT_OVERRUN = 4096;
const jint INTERRUPT_PARITY = 8192;
const jint EV_CTS = 8;
const jint EV_DSR = 16;
const jint EV_RING = 256;
const jint EV_RLSD = 32;
const jint EV_RXCHAR = 1;
//const jint EV_RXFLAG = 2; //Not supported
const jint EV_TXEMPTY = 4;
const jint events[] = {INTERRUPT_BREAK,
INTERRUPT_TX,
INTERRUPT_FRAME,
INTERRUPT_OVERRUN,
INTERRUPT_PARITY,
EV_CTS,
EV_DSR,
EV_RING,
EV_RLSD,
EV_RXCHAR,
//EV_RXFLAG, //Not supported
EV_TXEMPTY};
/* OK */
/*
* Collecting data for EventListener class (Linux have no implementation of "WaitCommEvent" function from Windows)
*
*/
JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_waitEvents
(JNIEnv *env, jobject object, jlong portHandle) {
jclass intClass = env->FindClass("[I");
jobjectArray returnArray = env->NewObjectArray(sizeof(events)/sizeof(jint), intClass, NULL);
/*Input buffer*/
jint bytesCountIn = 0;
ioctl(portHandle, FIONREAD, &bytesCountIn);
/*Output buffer*/
jint bytesCountOut = 0;
ioctl(portHandle, TIOCOUTQ, &bytesCountOut);
/*Lines status*/
int statusLines = getLinesStatus(portHandle);
jint statusCTS = 0;
jint statusDSR = 0;
jint statusRING = 0;
jint statusRLSD = 0;
/*CTS status*/
if(statusLines & TIOCM_CTS){
statusCTS = 1;
}
/*DSR status*/
if(statusLines & TIOCM_DSR){
statusDSR = 1;
}
/*RING status*/
if(statusLines & TIOCM_RNG){
statusRING = 1;
}
/*RLSD(DCD) status*/
if(statusLines & TIOCM_CAR){
statusRLSD = 1;
}
/*Interrupts*/
int interrupts[] = {-1, -1, -1, -1, -1};
getInterruptsCount(portHandle, interrupts);
jint interruptBreak = interrupts[0];
jint interruptTX = interrupts[1];
jint interruptFrame = interrupts[2];
jint interruptOverrun = interrupts[3];
jint interruptParity = interrupts[4];
for(int i = 0; i < sizeof(events)/sizeof(jint); i++){
jint returnValues[2];
switch(events[i]) {
case INTERRUPT_BREAK: //Interrupt Break - for BREAK event
returnValues[1] = interruptBreak;
goto forEnd;
case INTERRUPT_TX: //Interrupt TX - for TXEMPTY event
returnValues[1] = interruptTX;
goto forEnd;
case INTERRUPT_FRAME: //Interrupt Frame - for ERR event
returnValues[1] = interruptFrame;
goto forEnd;
case INTERRUPT_OVERRUN: //Interrupt Overrun - for ERR event
returnValues[1] = interruptOverrun;
goto forEnd;
case INTERRUPT_PARITY: //Interrupt Parity - for ERR event
returnValues[1] = interruptParity;
goto forEnd;
case EV_CTS:
returnValues[1] = statusCTS;
goto forEnd;
case EV_DSR:
returnValues[1] = statusDSR;
goto forEnd;
case EV_RING:
returnValues[1] = statusRING;
goto forEnd;
case EV_RLSD: /*DCD*/
returnValues[1] = statusRLSD;
goto forEnd;
case EV_RXCHAR:
returnValues[1] = bytesCountIn;
goto forEnd;
/*case EV_RXFLAG: // Event RXFLAG - Not supported
returnValues[0] = EV_RXFLAG;
returnValues[1] = 0;
goto forEnd;*/
case EV_TXEMPTY:
returnValues[1] = bytesCountOut;
goto forEnd;
}
forEnd: {
returnValues[0] = events[i];
jintArray singleResultArray = env->NewIntArray(2);
env->SetIntArrayRegion(singleResultArray, 0, 2, returnValues);
env->SetObjectArrayElement(returnArray, i, singleResultArray);
};
}
return returnArray;
}
/* OK */
/*
* Getting serial ports names like an a String array (String[])
*/
JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getSerialPortNames
(JNIEnv *env, jobject object){
//Don't needed in linux, implemented in java code (Note: null will be returned)
return NULL;
}
/* OK */
/*
* Getting lines status
*
* returnValues[0] - CTS
* returnValues[1] - DSR
* returnValues[2] - RING
* returnValues[3] - RLSD(DCD)
*/
JNIEXPORT jintArray JNICALL Java_jssc_SerialNativeInterface_getLinesStatus
(JNIEnv *env, jobject object, jlong portHandle){
jint returnValues[4];
for(jint i = 0; i < 4; i++){
returnValues[i] = 0;
}
jintArray returnArray = env->NewIntArray(4);
/*Lines status*/
int statusLines = getLinesStatus(portHandle);
/*CTS status*/
if(statusLines & TIOCM_CTS){
returnValues[0] = 1;
}
/*DSR status*/
if(statusLines & TIOCM_DSR){
returnValues[1] = 1;
}
/*RING status*/
if(statusLines & TIOCM_RNG){
returnValues[2] = 1;
}
/*RLSD(DCD) status*/
if(statusLines & TIOCM_CAR){
returnValues[3] = 1;
}
env->SetIntArrayRegion(returnArray, 0, 4, returnValues);
return returnArray;
}
java-simple-serial-connector-2.8.0/src/cpp/jssc_SerialNativeInterface.h 0000664 0000000 0000000 00000013520 12270474732 0026162 0 ustar 00root root 0000000 0000000 /* jSSC (Java Simple Serial Connector) - serial port communication library.
* © Alexey Sokolov (scream3r), 2010-2014.
*
* This file is part of jSSC.
*
* jSSC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jSSC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with jSSC. If not, see .
*
* If you use jSSC in public project you can inform me about this by e-mail,
* of course if you want it.
*
* e-mail: scream3r.org@gmail.com
* web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/
*/
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class jssc_SerialNativeInterface */
#ifndef _Included_jssc_SerialNativeInterface
#define _Included_jssc_SerialNativeInterface
#ifdef __cplusplus
extern "C" {
#endif
#undef jSSC_NATIVE_LIB_VERSION
#define jSSC_NATIVE_LIB_VERSION "2.8"
#undef jssc_SerialNativeInterface_OS_LINUX
#define jssc_SerialNativeInterface_OS_LINUX 0L
#undef jssc_SerialNativeInterface_OS_WINDOWS
#define jssc_SerialNativeInterface_OS_WINDOWS 1L
#undef jssc_SerialNativeInterface_OS_SOLARIS
#define jssc_SerialNativeInterface_OS_SOLARIS 2L
#undef jssc_SerialNativeInterface_OS_MAC_OS_X
#define jssc_SerialNativeInterface_OS_MAC_OS_X 3L
#undef jssc_SerialNativeInterface_ERR_PORT_BUSY
#define jssc_SerialNativeInterface_ERR_PORT_BUSY -1LL
#undef jssc_SerialNativeInterface_ERR_PORT_NOT_FOUND
#define jssc_SerialNativeInterface_ERR_PORT_NOT_FOUND -2LL
#undef jssc_SerialNativeInterface_ERR_PERMISSION_DENIED
#define jssc_SerialNativeInterface_ERR_PERMISSION_DENIED -3LL
#undef jssc_SerialNativeInterface_ERR_INCORRECT_SERIAL_PORT
#define jssc_SerialNativeInterface_ERR_INCORRECT_SERIAL_PORT -4LL
/*
* Class: jssc_SerialNativeInterface
* Method: getNativeLibraryVersion
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_jssc_SerialNativeInterface_getNativeLibraryVersion
(JNIEnv *, jobject);
/*
* Class: jssc_SerialNativeInterface
* Method: openPort
* Signature: (Ljava/lang/String;Z)J
*/
JNIEXPORT jlong JNICALL Java_jssc_SerialNativeInterface_openPort
(JNIEnv *, jobject, jstring, jboolean);
/*
* Class: jssc_SerialNativeInterface
* Method: setParams
* Signature: (JIIIIZZI)Z
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setParams
(JNIEnv *, jobject, jlong, jint, jint, jint, jint, jboolean, jboolean, jint);
/*
* Class: jssc_SerialNativeInterface
* Method: purgePort
* Signature: (JI)Z
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_purgePort
(JNIEnv *, jobject, jlong, jint);
/*
* Class: jssc_SerialNativeInterface
* Method: closePort
* Signature: (J)Z
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_closePort
(JNIEnv *, jobject, jlong);
/*
* Class: jssc_SerialNativeInterface
* Method: setEventsMask
* Signature: (JI)Z
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setEventsMask
(JNIEnv *, jobject, jlong, jint);
/*
* Class: jssc_SerialNativeInterface
* Method: getEventsMask
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_jssc_SerialNativeInterface_getEventsMask
(JNIEnv *, jobject, jlong);
/*
* Class: jssc_SerialNativeInterface
* Method: waitEvents
* Signature: (J)[[I
*/
JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_waitEvents
(JNIEnv *, jobject, jlong);
/*
* Class: jssc_SerialNativeInterface
* Method: setRTS
* Signature: (JZ)Z
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setRTS
(JNIEnv *, jobject, jlong, jboolean);
/*
* Class: jssc_SerialNativeInterface
* Method: setDTR
* Signature: (JZ)Z
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setDTR
(JNIEnv *, jobject, jlong, jboolean);
/*
* Class: jssc_SerialNativeInterface
* Method: readBytes
* Signature: (JI)[B
*/
JNIEXPORT jbyteArray JNICALL Java_jssc_SerialNativeInterface_readBytes
(JNIEnv *, jobject, jlong, jint);
/*
* Class: jssc_SerialNativeInterface
* Method: writeBytes
* Signature: (J[B)Z
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes
(JNIEnv *, jobject, jlong, jbyteArray);
/*
* Class: jssc_SerialNativeInterface
* Method: getBuffersBytesCount
* Signature: (J)[I
*/
JNIEXPORT jintArray JNICALL Java_jssc_SerialNativeInterface_getBuffersBytesCount
(JNIEnv *, jobject, jlong);
/*
* Class: jssc_SerialNativeInterface
* Method: setFlowControlMode
* Signature: (JI)Z
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setFlowControlMode
(JNIEnv *, jobject, jlong, jint);
/*
* Class: jssc_SerialNativeInterface
* Method: getFlowControlMode
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_jssc_SerialNativeInterface_getFlowControlMode
(JNIEnv *, jobject, jlong);
/*
* Class: jssc_SerialNativeInterface
* Method: getSerialPortNames
* Signature: ()[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getSerialPortNames
(JNIEnv *, jobject);
/*
* Class: jssc_SerialNativeInterface
* Method: getLinesStatus
* Signature: (J)[I
*/
JNIEXPORT jintArray JNICALL Java_jssc_SerialNativeInterface_getLinesStatus
(JNIEnv *, jobject, jlong);
/*
* Class: jssc_SerialNativeInterface
* Method: sendBreak
* Signature: (JI)Z
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_sendBreak
(JNIEnv *, jobject, jlong, jint);
#ifdef __cplusplus
}
#endif
#endif
java-simple-serial-connector-2.8.0/src/cpp/windows/ 0000775 0000000 0000000 00000000000 12270474732 0022251 5 ustar 00root root 0000000 0000000 java-simple-serial-connector-2.8.0/src/cpp/windows/jssc.c++ 0000664 0000000 0000000 00000054317 12270474732 0023517 0 ustar 00root root 0000000 0000000 /* jSSC (Java Simple Serial Connector) - serial port communication library.
* © Alexey Sokolov (scream3r), 2010-2014.
*
* This file is part of jSSC.
*
* jSSC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jSSC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with jSSC. If not, see .
*
* If you use jSSC in public project you can inform me about this by e-mail,
* of course if you want it.
*
* e-mail: scream3r.org@gmail.com
* web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/
*/
#include
#include
#include
#include "../jssc_SerialNativeInterface.h"
//#include
/*
* Get native library version
*/
JNIEXPORT jstring JNICALL Java_jssc_SerialNativeInterface_getNativeLibraryVersion(JNIEnv *env, jobject object) {
return env->NewStringUTF(jSSC_NATIVE_LIB_VERSION);
}
/*
* Port opening.
*
* In 2.2.0 added useTIOCEXCL (not used in Windows, only for compatibility with _nix version)
*/
JNIEXPORT jlong JNICALL Java_jssc_SerialNativeInterface_openPort(JNIEnv *env, jobject object, jstring portName, jboolean useTIOCEXCL){
char prefix[] = "\\\\.\\";
const char* port = env->GetStringUTFChars(portName, JNI_FALSE);
//since 2.1.0 -> string concat fix
char portFullName[strlen(prefix) + strlen(port) + 1];
strcpy(portFullName, prefix);
strcat(portFullName, port);
//<- since 2.1.0
HANDLE hComm = CreateFile(portFullName,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
env->ReleaseStringUTFChars(portName, port);
//since 2.3.0 ->
if(hComm != INVALID_HANDLE_VALUE){
DCB *dcb = new DCB();
if(!GetCommState(hComm, dcb)){
CloseHandle(hComm);//since 2.7.0
hComm = (HANDLE)jssc_SerialNativeInterface_ERR_INCORRECT_SERIAL_PORT;//(-4)Incorrect serial port
}
delete dcb;
}
else {
DWORD errorValue = GetLastError();
if(errorValue == ERROR_ACCESS_DENIED){
hComm = (HANDLE)jssc_SerialNativeInterface_ERR_PORT_BUSY;//(-1)Port busy
}
else if(errorValue == ERROR_FILE_NOT_FOUND){
hComm = (HANDLE)jssc_SerialNativeInterface_ERR_PORT_NOT_FOUND;//(-2)Port not found
}
}
//<- since 2.3.0
return (jlong)hComm;//since 2.4.0 changed to jlong
};
/*
* Setting serial port params.
*
* In 2.6.0 added flags (not used in Windows, only for compatibility with _nix version)
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setParams
(JNIEnv *env, jobject object, jlong portHandle, jint baudRate, jint byteSize, jint stopBits, jint parity, jboolean setRTS, jboolean setDTR, jint flags){
HANDLE hComm = (HANDLE)portHandle;
DCB *dcb = new DCB();
jboolean returnValue = JNI_FALSE;
if(GetCommState(hComm, dcb)){
dcb->BaudRate = baudRate;
dcb->ByteSize = byteSize;
dcb->StopBits = stopBits;
dcb->Parity = parity;
//since 0.8 ->
if(setRTS == JNI_TRUE){
dcb->fRtsControl = RTS_CONTROL_ENABLE;
}
else {
dcb->fRtsControl = RTS_CONTROL_DISABLE;
}
if(setDTR == JNI_TRUE){
dcb->fDtrControl = DTR_CONTROL_ENABLE;
}
else {
dcb->fDtrControl = DTR_CONTROL_DISABLE;
}
dcb->fOutxCtsFlow = FALSE;
dcb->fOutxDsrFlow = FALSE;
dcb->fDsrSensitivity = FALSE;
dcb->fTXContinueOnXoff = TRUE;
dcb->fOutX = FALSE;
dcb->fInX = FALSE;
dcb->fErrorChar = FALSE;
dcb->fNull = FALSE;
dcb->fAbortOnError = FALSE;
dcb->XonLim = 2048;
dcb->XoffLim = 512;
dcb->XonChar = (char)17; //DC1
dcb->XoffChar = (char)19; //DC3
//<- since 0.8
if(SetCommState(hComm, dcb)){
//since 2.1.0 -> previously setted timeouts by another application should be cleared
COMMTIMEOUTS *lpCommTimeouts = new COMMTIMEOUTS();
lpCommTimeouts->ReadIntervalTimeout = 0;
lpCommTimeouts->ReadTotalTimeoutConstant = 0;
lpCommTimeouts->ReadTotalTimeoutMultiplier = 0;
lpCommTimeouts->WriteTotalTimeoutConstant = 0;
lpCommTimeouts->WriteTotalTimeoutMultiplier = 0;
if(SetCommTimeouts(hComm, lpCommTimeouts)){
returnValue = JNI_TRUE;
}
delete lpCommTimeouts;
//<- since 2.1.0
}
}
delete dcb;
return returnValue;
}
/*
* PurgeComm
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_purgePort
(JNIEnv *env, jobject object, jlong portHandle, jint flags){
HANDLE hComm = (HANDLE)portHandle;
DWORD dwFlags = (DWORD)flags;
return (PurgeComm(hComm, dwFlags) ? JNI_TRUE : JNI_FALSE);
}
/*
* Port closing
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_closePort
(JNIEnv *env, jobject object, jlong portHandle){
HANDLE hComm = (HANDLE)portHandle;
return (CloseHandle(hComm) ? JNI_TRUE : JNI_FALSE);
}
/*
* Set events mask
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setEventsMask
(JNIEnv *env, jobject object, jlong portHandle, jint mask){
HANDLE hComm = (HANDLE)portHandle;
DWORD dwEvtMask = (DWORD)mask;
return (SetCommMask(hComm, dwEvtMask) ? JNI_TRUE : JNI_FALSE);
}
/*
* Get events mask
*/
JNIEXPORT jint JNICALL Java_jssc_SerialNativeInterface_getEventsMask
(JNIEnv *env, jobject object, jlong portHandle){
HANDLE hComm = (HANDLE)portHandle;
DWORD lpEvtMask;
if(GetCommMask(hComm, &lpEvtMask)){
return (jint)lpEvtMask;
}
else {
return -1;
}
}
/*
* Change RTS line state (ON || OFF)
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setRTS
(JNIEnv *env, jobject object, jlong portHandle, jboolean enabled){
HANDLE hComm = (HANDLE)portHandle;
if(enabled == JNI_TRUE){
return (EscapeCommFunction(hComm, SETRTS) ? JNI_TRUE : JNI_FALSE);
}
else {
return (EscapeCommFunction(hComm, CLRRTS) ? JNI_TRUE : JNI_FALSE);
}
}
/*
* Change DTR line state (ON || OFF)
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setDTR
(JNIEnv *env, jobject object, jlong portHandle, jboolean enabled){
HANDLE hComm = (HANDLE)portHandle;
if(enabled == JNI_TRUE){
return (EscapeCommFunction(hComm, SETDTR) ? JNI_TRUE : JNI_FALSE);
}
else {
return (EscapeCommFunction(hComm, CLRDTR) ? JNI_TRUE : JNI_FALSE);
}
}
/*
* Write data to port
* portHandle - port handle
* buffer - byte array for sending
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes
(JNIEnv *env, jobject object, jlong portHandle, jbyteArray buffer){
HANDLE hComm = (HANDLE)portHandle;
DWORD lpNumberOfBytesTransferred;
DWORD lpNumberOfBytesWritten;
OVERLAPPED *overlapped = new OVERLAPPED();
jboolean returnValue = JNI_FALSE;
jbyte* jBuffer = env->GetByteArrayElements(buffer, JNI_FALSE);
overlapped->hEvent = CreateEventA(NULL, true, false, NULL);
if(WriteFile(hComm, jBuffer, (DWORD)env->GetArrayLength(buffer), &lpNumberOfBytesWritten, overlapped)){
returnValue = JNI_TRUE;
}
else if(GetLastError() == ERROR_IO_PENDING){
if(WaitForSingleObject(overlapped->hEvent, INFINITE) == WAIT_OBJECT_0){
if(GetOverlappedResult(hComm, overlapped, &lpNumberOfBytesTransferred, false)){
returnValue = JNI_TRUE;
}
}
}
env->ReleaseByteArrayElements(buffer, jBuffer, 0);
CloseHandle(overlapped->hEvent);
delete overlapped;
return returnValue;
}
/*
* Read data from port
* portHandle - port handle
* byteCount - count of bytes for reading
*/
JNIEXPORT jbyteArray JNICALL Java_jssc_SerialNativeInterface_readBytes
(JNIEnv *env, jobject object, jlong portHandle, jint byteCount){
HANDLE hComm = (HANDLE)portHandle;
DWORD lpNumberOfBytesTransferred;
DWORD lpNumberOfBytesRead;
OVERLAPPED *overlapped = new OVERLAPPED();
jbyte lpBuffer[byteCount];
jbyteArray returnArray = env->NewByteArray(byteCount);
overlapped->hEvent = CreateEventA(NULL, true, false, NULL);
if(ReadFile(hComm, lpBuffer, (DWORD)byteCount, &lpNumberOfBytesRead, overlapped)){
env->SetByteArrayRegion(returnArray, 0, byteCount, lpBuffer);
}
else if(GetLastError() == ERROR_IO_PENDING){
if(WaitForSingleObject(overlapped->hEvent, INFINITE) == WAIT_OBJECT_0){
if(GetOverlappedResult(hComm, overlapped, &lpNumberOfBytesTransferred, false)){
env->SetByteArrayRegion(returnArray, 0, byteCount, lpBuffer);
}
}
}
CloseHandle(overlapped->hEvent);
delete overlapped;
return returnArray;
}
/*
* Get bytes count in serial port buffers (Input and Output)
*/
JNIEXPORT jintArray JNICALL Java_jssc_SerialNativeInterface_getBuffersBytesCount
(JNIEnv *env, jobject object, jlong portHandle){
HANDLE hComm = (HANDLE)portHandle;
jint returnValues[2];
returnValues[0] = -1;
returnValues[1] = -1;
jintArray returnArray = env->NewIntArray(2);
DWORD lpErrors;
COMSTAT *comstat = new COMSTAT();
if(ClearCommError(hComm, &lpErrors, comstat)){
returnValues[0] = (jint)comstat->cbInQue;
returnValues[1] = (jint)comstat->cbOutQue;
}
else {
returnValues[0] = -1;
returnValues[1] = -1;
}
delete comstat;
env->SetIntArrayRegion(returnArray, 0, 2, returnValues);
return returnArray;
}
//since 0.8 ->
const jint FLOWCONTROL_NONE = 0;
const jint FLOWCONTROL_RTSCTS_IN = 1;
const jint FLOWCONTROL_RTSCTS_OUT = 2;
const jint FLOWCONTROL_XONXOFF_IN = 4;
const jint FLOWCONTROL_XONXOFF_OUT = 8;
//<- since 0.8
/*
* Setting flow control mode
*
* since 0.8
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setFlowControlMode
(JNIEnv *env, jobject object, jlong portHandle, jint mask){
HANDLE hComm = (HANDLE)portHandle;
jboolean returnValue = JNI_FALSE;
DCB *dcb = new DCB();
if(GetCommState(hComm, dcb)){
dcb->fRtsControl = RTS_CONTROL_ENABLE;
dcb->fOutxCtsFlow = FALSE;
dcb->fOutX = FALSE;
dcb->fInX = FALSE;
if(mask != FLOWCONTROL_NONE){
if((mask & FLOWCONTROL_RTSCTS_IN) == FLOWCONTROL_RTSCTS_IN){
dcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
}
if((mask & FLOWCONTROL_RTSCTS_OUT) == FLOWCONTROL_RTSCTS_OUT){
dcb->fOutxCtsFlow = TRUE;
}
if((mask & FLOWCONTROL_XONXOFF_IN) == FLOWCONTROL_XONXOFF_IN){
dcb->fInX = TRUE;
}
if((mask & FLOWCONTROL_XONXOFF_OUT) == FLOWCONTROL_XONXOFF_OUT){
dcb->fOutX = TRUE;
}
}
if(SetCommState(hComm, dcb)){
returnValue = JNI_TRUE;
}
}
delete dcb;
return returnValue;
}
/*
* Getting flow control mode
*
* since 0.8
*/
JNIEXPORT jint JNICALL Java_jssc_SerialNativeInterface_getFlowControlMode
(JNIEnv *env, jobject object, jlong portHandle){
HANDLE hComm = (HANDLE)portHandle;
jint returnValue = 0;
DCB *dcb = new DCB();
if(GetCommState(hComm, dcb)){
if(dcb->fRtsControl == RTS_CONTROL_HANDSHAKE){
returnValue |= FLOWCONTROL_RTSCTS_IN;
}
if(dcb->fOutxCtsFlow == TRUE){
returnValue |= FLOWCONTROL_RTSCTS_OUT;
}
if(dcb->fInX == TRUE){
returnValue |= FLOWCONTROL_XONXOFF_IN;
}
if(dcb->fOutX == TRUE){
returnValue |= FLOWCONTROL_XONXOFF_OUT;
}
}
delete dcb;
return returnValue;
}
/*
* Send break for setted duration
*
* since 0.8
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_sendBreak
(JNIEnv *env, jobject object, jlong portHandle, jint duration){
HANDLE hComm = (HANDLE)portHandle;
jboolean returnValue = JNI_FALSE;
if(duration > 0){
if(SetCommBreak(hComm) > 0){
Sleep(duration);
if(ClearCommBreak(hComm) > 0){
returnValue = JNI_TRUE;
}
}
}
return returnValue;
}
/*
* Wait event
* portHandle - port handle
*/
JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_waitEvents
(JNIEnv *env, jobject object, jlong portHandle) {
HANDLE hComm = (HANDLE)portHandle;
DWORD lpEvtMask = 0;
DWORD lpNumberOfBytesTransferred = 0;
OVERLAPPED *overlapped = new OVERLAPPED();
jclass intClass = env->FindClass("[I");
jobjectArray returnArray;
boolean functionSuccessful = false;
overlapped->hEvent = CreateEventA(NULL, true, false, NULL);
if(WaitCommEvent(hComm, &lpEvtMask, overlapped)){
functionSuccessful = true;
}
else if(GetLastError() == ERROR_IO_PENDING){
if(WaitForSingleObject(overlapped->hEvent, INFINITE) == WAIT_OBJECT_0){
if(GetOverlappedResult(hComm, overlapped, &lpNumberOfBytesTransferred, false)){
functionSuccessful = true;
}
}
}
if(functionSuccessful){
boolean executeGetCommModemStatus = false;
boolean executeClearCommError = false;
DWORD events[9];//fixed since 0.8 (old value is 8)
jint eventsCount = 0;
if((EV_BREAK & lpEvtMask) == EV_BREAK){
events[eventsCount] = EV_BREAK;
eventsCount++;
}
if((EV_CTS & lpEvtMask) == EV_CTS){
events[eventsCount] = EV_CTS;
eventsCount++;
executeGetCommModemStatus = true;
}
if((EV_DSR & lpEvtMask) == EV_DSR){
events[eventsCount] = EV_DSR;
eventsCount++;
executeGetCommModemStatus = true;
}
if((EV_ERR & lpEvtMask) == EV_ERR){
events[eventsCount] = EV_ERR;
eventsCount++;
executeClearCommError = true;
}
if((EV_RING & lpEvtMask) == EV_RING){
events[eventsCount] = EV_RING;
eventsCount++;
executeGetCommModemStatus = true;
}
if((EV_RLSD & lpEvtMask) == EV_RLSD){
events[eventsCount] = EV_RLSD;
eventsCount++;
executeGetCommModemStatus = true;
}
if((EV_RXCHAR & lpEvtMask) == EV_RXCHAR){
events[eventsCount] = EV_RXCHAR;
eventsCount++;
executeClearCommError = true;
}
if((EV_RXFLAG & lpEvtMask) == EV_RXFLAG){
events[eventsCount] = EV_RXFLAG;
eventsCount++;
executeClearCommError = true;
}
if((EV_TXEMPTY & lpEvtMask) == EV_TXEMPTY){
events[eventsCount] = EV_TXEMPTY;
eventsCount++;
executeClearCommError = true;
}
/*
* Execute GetCommModemStatus function if it's needed (get lines status)
*/
jint statusCTS = 0;
jint statusDSR = 0;
jint statusRING = 0;
jint statusRLSD = 0;
boolean successGetCommModemStatus = false;
if(executeGetCommModemStatus){
DWORD lpModemStat;
if(GetCommModemStatus(hComm, &lpModemStat)){
successGetCommModemStatus = true;
if((MS_CTS_ON & lpModemStat) == MS_CTS_ON){
statusCTS = 1;
}
if((MS_DSR_ON & lpModemStat) == MS_DSR_ON){
statusDSR = 1;
}
if((MS_RING_ON & lpModemStat) == MS_RING_ON){
statusRING = 1;
}
if((MS_RLSD_ON & lpModemStat) == MS_RLSD_ON){
statusRLSD = 1;
}
}
else {
jint lastError = (jint)GetLastError();
statusCTS = lastError;
statusDSR = lastError;
statusRING = lastError;
statusRLSD = lastError;
}
}
/*
* Execute ClearCommError function if it's needed (get count of bytes in buffers and errors)
*/
jint bytesCountIn = 0;
jint bytesCountOut = 0;
jint communicationsErrors = 0;
boolean successClearCommError = false;
if(executeClearCommError){
DWORD lpErrors;
COMSTAT *comstat = new COMSTAT();
if(ClearCommError(hComm, &lpErrors, comstat)){
successClearCommError = true;
bytesCountIn = (jint)comstat->cbInQue;
bytesCountOut = (jint)comstat->cbOutQue;
communicationsErrors = (jint)lpErrors;
}
else {
jint lastError = (jint)GetLastError();
bytesCountIn = lastError;
bytesCountOut = lastError;
communicationsErrors = lastError;
}
delete comstat;
}
/*
* Create int[][] for events values
*/
returnArray = env->NewObjectArray(eventsCount, intClass, NULL);
/*
* Set events values
*/
for(jint i = 0; i < eventsCount; i++){
jint returnValues[2];
switch(events[i]){
case EV_BREAK:
returnValues[0] = (jint)events[i];
returnValues[1] = 0;
goto forEnd;
case EV_CTS:
returnValues[1] = statusCTS;
goto modemStatus;
case EV_DSR:
returnValues[1] = statusDSR;
goto modemStatus;
case EV_ERR:
returnValues[1] = communicationsErrors;
goto bytesAndErrors;
case EV_RING:
returnValues[1] = statusRING;
goto modemStatus;
case EV_RLSD:
returnValues[1] = statusRLSD;
goto modemStatus;
case EV_RXCHAR:
returnValues[1] = bytesCountIn;
goto bytesAndErrors;
case EV_RXFLAG:
returnValues[1] = bytesCountIn;
goto bytesAndErrors;
case EV_TXEMPTY:
returnValues[1] = bytesCountOut;
goto bytesAndErrors;
default:
returnValues[0] = (jint)events[i];
returnValues[1] = 0;
goto forEnd;
};
modemStatus: {
if(successGetCommModemStatus){
returnValues[0] = (jint)events[i];
}
else {
returnValues[0] = -1;
}
goto forEnd;
}
bytesAndErrors: {
if(successClearCommError){
returnValues[0] = (jint)events[i];
}
else {
returnValues[0] = -1;
}
goto forEnd;
}
forEnd: {
jintArray singleResultArray = env->NewIntArray(2);
env->SetIntArrayRegion(singleResultArray, 0, 2, returnValues);
env->SetObjectArrayElement(returnArray, i, singleResultArray);
};
}
}
else {
returnArray = env->NewObjectArray(1, intClass, NULL);
jint returnValues[2];
returnValues[0] = -1;
returnValues[1] = (jint)GetLastError();
jintArray singleResultArray = env->NewIntArray(2);
env->SetIntArrayRegion(singleResultArray, 0, 2, returnValues);
env->SetObjectArrayElement(returnArray, 0, singleResultArray);
};
CloseHandle(overlapped->hEvent);
delete overlapped;
return returnArray;
}
/*
* Get serial port names
*/
JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getSerialPortNames
(JNIEnv *env, jobject object){
HKEY phkResult;
LPCSTR lpSubKey = "HARDWARE\\DEVICEMAP\\SERIALCOMM\\";
jobjectArray returnArray = NULL;
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &phkResult) == ERROR_SUCCESS){
boolean hasMoreElements = true;
DWORD keysCount = 0;
char valueName[256];
DWORD valueNameSize;
DWORD enumResult;
while(hasMoreElements){
valueNameSize = 256;
enumResult = RegEnumValueA(phkResult, keysCount, valueName, &valueNameSize, NULL, NULL, NULL, NULL);
if(enumResult == ERROR_SUCCESS){
keysCount++;
}
else if(enumResult == ERROR_NO_MORE_ITEMS){
hasMoreElements = false;
}
else {
hasMoreElements = false;
}
}
if(keysCount > 0){
jclass stringClass = env->FindClass("java/lang/String");
returnArray = env->NewObjectArray((jsize)keysCount, stringClass, NULL);
char lpValueName[256];
DWORD lpcchValueName;
byte lpData[256];
DWORD lpcbData;
DWORD result;
for(DWORD i = 0; i < keysCount; i++){
lpcchValueName = 256;
lpcbData = 256;
result = RegEnumValueA(phkResult, i, lpValueName, &lpcchValueName, NULL, NULL, lpData, &lpcbData);
if(result == ERROR_SUCCESS){
env->SetObjectArrayElement(returnArray, i, env->NewStringUTF((char*)lpData));
}
}
}
CloseHandle(phkResult);
}
return returnArray;
}
/*
* Get lines status
*
* returnValues[0] - CTS
* returnValues[1] - DSR
* returnValues[2] - RING
* returnValues[3] - RLSD
*
*/
JNIEXPORT jintArray JNICALL Java_jssc_SerialNativeInterface_getLinesStatus
(JNIEnv *env, jobject object, jlong portHandle){
HANDLE hComm = (HANDLE)portHandle;
DWORD lpModemStat;
jint returnValues[4];
for(jint i = 0; i < 4; i++){
returnValues[i] = 0;
}
jintArray returnArray = env->NewIntArray(4);
if(GetCommModemStatus(hComm, &lpModemStat)){
if((MS_CTS_ON & lpModemStat) == MS_CTS_ON){
returnValues[0] = 1;
}
if((MS_DSR_ON & lpModemStat) == MS_DSR_ON){
returnValues[1] = 1;
}
if((MS_RING_ON & lpModemStat) == MS_RING_ON){
returnValues[2] = 1;
}
if((MS_RLSD_ON & lpModemStat) == MS_RLSD_ON){
returnValues[3] = 1;
}
}
env->SetIntArrayRegion(returnArray, 0, 4, returnValues);
return returnArray;
}
java-simple-serial-connector-2.8.0/src/java/ 0000775 0000000 0000000 00000000000 12270474732 0020716 5 ustar 00root root 0000000 0000000 java-simple-serial-connector-2.8.0/src/java/jssc/ 0000775 0000000 0000000 00000000000 12270474732 0021660 5 ustar 00root root 0000000 0000000 java-simple-serial-connector-2.8.0/src/java/jssc/SerialNativeInterface.java 0000664 0000000 0000000 00000035555 12270474732 0026747 0 ustar 00root root 0000000 0000000 /* jSSC (Java Simple Serial Connector) - serial port communication library.
* © Alexey Sokolov (scream3r), 2010-2014.
*
* This file is part of jSSC.
*
* jSSC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jSSC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with jSSC. If not, see .
*
* If you use jSSC in public project you can inform me about this by e-mail,
* of course if you want it.
*
* e-mail: scream3r.org@gmail.com
* web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/
*/
package jssc;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
*
* @author scream3r
*/
public class SerialNativeInterface {
private static final String libVersion = "2.8"; //jSSC-2.8.0 Release from 24.01.2014
private static final String libMinorSuffix = "0"; //since 0.9.0
public static final int OS_LINUX = 0;
public static final int OS_WINDOWS = 1;
public static final int OS_SOLARIS = 2;//since 0.9.0
public static final int OS_MAC_OS_X = 3;//since 0.9.0
private static int osType = -1;
/**
* @since 2.3.0
*/
public static final long ERR_PORT_BUSY = -1;
/**
* @since 2.3.0
*/
public static final long ERR_PORT_NOT_FOUND = -2;
/**
* @since 2.3.0
*/
public static final long ERR_PERMISSION_DENIED = -3;
/**
* @since 2.3.0
*/
public static final long ERR_INCORRECT_SERIAL_PORT = -4;
/**
* @since 2.6.0
*/
public static final String PROPERTY_JSSC_NO_TIOCEXCL = "JSSC_NO_TIOCEXCL";
/**
* @since 2.6.0
*/
public static final String PROPERTY_JSSC_IGNPAR = "JSSC_IGNPAR";
/**
* @since 2.6.0
*/
public static final String PROPERTY_JSSC_PARMRK = "JSSC_PARMRK";
static {
String libFolderPath;
String libName;
String osName = System.getProperty("os.name");
String architecture = System.getProperty("os.arch");
String userHome = System.getProperty("user.home");
String fileSeparator = System.getProperty("file.separator");
String tmpFolder = System.getProperty("java.io.tmpdir");
//since 2.3.0 ->
String libRootFolder = new File(userHome).canWrite() ? userHome : tmpFolder;
//<- since 2.3.0
String javaLibPath = System.getProperty("java.library.path");//since 2.1.0
if(osName.equals("Linux")){
osName = "linux";
osType = OS_LINUX;
}
else if(osName.startsWith("Win")){
osName = "windows";
osType = OS_WINDOWS;
}//since 0.9.0 ->
else if(osName.equals("SunOS")){
osName = "solaris";
osType = OS_SOLARIS;
}
else if(osName.equals("Mac OS X") || osName.equals("Darwin")){//os.name "Darwin" since 2.6.0
osName = "mac_os_x";
osType = OS_MAC_OS_X;
}//<- since 0.9.0
if(architecture.equals("i386") || architecture.equals("i686")){
architecture = "x86";
}
else if(architecture.equals("amd64") || architecture.equals("universal")){//os.arch "universal" since 2.6.0
architecture = "x86_64";
}
else if(architecture.equals("arm")) {//since 2.1.0
String floatStr = "sf";
if(javaLibPath.toLowerCase().contains("gnueabihf") || javaLibPath.toLowerCase().contains("armhf")){
floatStr = "hf";
}
else {
try {
Process readelfProcess = Runtime.getRuntime().exec("readelf -A /proc/self/exe");
BufferedReader reader = new BufferedReader(new InputStreamReader(readelfProcess.getInputStream()));
String buffer = "";
while((buffer = reader.readLine()) != null && !buffer.isEmpty()){
if(buffer.toLowerCase().contains("Tag_ABI_VFP_args".toLowerCase())){
floatStr = "hf";
break;
}
}
reader.close();
}
catch (Exception ex) {
//Do nothing
}
}
architecture = "arm" + floatStr;
}
libFolderPath = libRootFolder + fileSeparator + ".jssc" + fileSeparator + osName;
libName = "jSSC-" + libVersion + "_" + architecture;
libName = System.mapLibraryName(libName);
if(libName.endsWith(".dylib")){//Since 2.1.0 MacOSX 10.8 fix
libName = libName.replace(".dylib", ".jnilib");
}
boolean loadLib = false;
if(isLibFolderExist(libFolderPath)){
if(isLibFileExist(libFolderPath + fileSeparator + libName)){
loadLib = true;
}
else {
if(extractLib((libFolderPath + fileSeparator + libName), osName, libName)){
loadLib = true;
}
}
}
else {
if(new File(libFolderPath).mkdirs()){
if(extractLib((libFolderPath + fileSeparator + libName), osName, libName)){
loadLib = true;
}
}
}
if (loadLib) {
System.load(libFolderPath + fileSeparator + libName);
String versionBase = getLibraryBaseVersion();
String versionNative = getNativeLibraryVersion();
if (!versionBase.equals(versionNative)) {
System.err.println("Warning! jSSC Java and Native versions mismatch (Java: " + versionBase + ", Native: " + versionNative + ")");
}
}
}
/**
* Is library folder exists
*
* @param libFolderPath
*
* @since 0.8
*/
private static boolean isLibFolderExist(String libFolderPath) {
boolean returnValue = false;
File folder = new File(libFolderPath);
if(folder.exists() && folder.isDirectory()){
returnValue = true;
}
return returnValue;
}
/**
* Is library file exists
*
* @param libFilePath
*
* @since 0.8
*/
private static boolean isLibFileExist(String libFilePath) {
boolean returnValue = false;
File folder = new File(libFilePath);
if(folder.exists() && folder.isFile()){
returnValue = true;
}
return returnValue;
}
/**
* Extract lib to lib folder
*
* @param libFilePath
* @param osName
* @param libName
*
* @since 0.8
*/
private static boolean extractLib(String libFilePath, String osName, String libName) {
boolean returnValue = false;
File libFile = new File(libFilePath);
InputStream input = null;
FileOutputStream output = null;
input = SerialNativeInterface.class.getResourceAsStream("/libs/" + osName + "/" + libName);
if(input != null){
int read;
byte[] buffer = new byte[4096];
try {
output = new FileOutputStream(libFilePath);
while((read = input.read(buffer)) != -1){
output.write(buffer, 0, read);
}
output.close();
input.close();
returnValue = true;
}
catch (Exception ex) {
try {
output.close();
if(libFile.exists()){
libFile.delete();
}
}
catch (Exception ex_out) {
//Do nothing
}
try {
input.close();
}
catch (Exception ex_in) {
//Do nothing
}
}
}
return returnValue;
}
/**
* Get OS type (OS_LINUX || OS_WINDOWS || OS_SOLARIS)
*
* @since 0.8
*/
public static int getOsType() {
return osType;
}
/**
* Get jSSC version. The version of library is Base Version + Minor Suffix
*
* @since 0.8
*/
public static String getLibraryVersion() {
return libVersion + "." + libMinorSuffix;
}
/**
* Get jSSC Base Version
*
* @since 0.9.0
*/
public static String getLibraryBaseVersion() {
return libVersion;
}
/**
* Get jSSC minor suffix. For example in version 0.8.1 - 1 is a minor suffix
*
* @since 0.9.0
*/
public static String getLibraryMinorSuffix() {
return libMinorSuffix;
}
/**
* Get jSSC native library version
*
* @return native lib version (for jSSC-2.8.0 should be 2.8 for example)
*
* @since 2.8.0
*/
public static native String getNativeLibraryVersion();
/**
* Open port
*
* @param portName name of port for opening
* @param useTIOCEXCL enable/disable using of TIOCEXCL. Take effect only on *nix based systems
*
* @return handle of opened port or -1 if opening of the port was unsuccessful
*/
public native long openPort(String portName, boolean useTIOCEXCL);
/**
* Setting the parameters of opened port
*
* @param handle handle of opened port
* @param baudRate data transfer rate
* @param dataBits number of data bits
* @param stopBits number of stop bits
* @param parity parity
* @param setRTS initial state of RTS line (ON/OFF)
* @param setDTR initial state of DTR line (ON/OFF)
* @param flags additional Native settings. Take effect only on *nix based systems
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*/
public native boolean setParams(long handle, int baudRate, int dataBits, int stopBits, int parity, boolean setRTS, boolean setDTR, int flags);
/**
* Purge of input and output buffer
*
* @param handle handle of opened port
* @param flags flags specifying required actions for purgePort method
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*/
public native boolean purgePort(long handle, int flags);
/**
* Close port
*
* @param handle handle of opened port
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*/
public native boolean closePort(long handle);
/**
* Set events mask
*
* @param handle handle of opened port
* @param mask events mask
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*/
public native boolean setEventsMask(long handle, int mask);
/**
* Get events mask
*
* @param handle handle of opened port
*
* @return Method returns event mask as a variable of int type
*/
public native int getEventsMask(long handle);
/**
* Wait events
*
* @param handle handle of opened port
*
* @return Method returns two-dimensional array containing event types and their values
* (events[i][0] - event type, events[i][1] - event value).
*/
public native int[][] waitEvents(long handle);
/**
* Change RTS line state
*
* @param handle handle of opened port
* @param value true - ON, false - OFF
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*/
public native boolean setRTS(long handle, boolean value);
/**
* Change DTR line state
*
* @param handle handle of opened port
* @param value true - ON, false - OFF
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*/
public native boolean setDTR(long handle, boolean value);
/**
* Read data from port
*
* @param handle handle of opened port
* @param byteCount count of bytes required to read
*
* @return Method returns the array of read bytes
*/
public native byte[] readBytes(long handle, int byteCount);
/**
* Write data to port
*
* @param handle handle of opened port
* @param buffer array of bytes to write
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*/
public native boolean writeBytes(long handle, byte[] buffer);
/**
* Get bytes count in buffers of port
*
* @param handle handle of opened port
*
* @return Method returns the array that contains info about bytes count in buffers:
*
element 0 - input buffer
*
element 1 - output buffer
*
* @since 0.8
*/
public native int[] getBuffersBytesCount(long handle);
/**
* Set flow control mode
*
* @param handle handle of opened port
* @param mask mask of flow control mode
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @since 0.8
*/
public native boolean setFlowControlMode(long handle, int mask);
/**
* Get flow control mode
*
* @param handle handle of opened port
*
* @return Mask of setted flow control mode
*
* @since 0.8
*/
public native int getFlowControlMode(long handle);
/**
* Get serial port names like an array of String
*
* @return unsorted array of String with port names
*/
public native String[] getSerialPortNames();
/**
* Getting lines states
*
* @param handle handle of opened port
*
* @return Method returns the array containing information about lines in following order:
*
element 0 - CTS line state
*
element 1 - DSR line state
*
element 2 - RING line state
*
element 3 - RLSD line state
*/
public native int[] getLinesStatus(long handle);
/**
* Send Break singnal for setted duration
*
* @param handle handle of opened port
* @param duration duration of Break signal
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @since 0.8
*/
public native boolean sendBreak(long handle, int duration);
}
java-simple-serial-connector-2.8.0/src/java/jssc/SerialPort.java 0000664 0000000 0000000 00000133531 12270474732 0024615 0 ustar 00root root 0000000 0000000 /* jSSC (Java Simple Serial Connector) - serial port communication library.
* © Alexey Sokolov (scream3r), 2010-2014.
*
* This file is part of jSSC.
*
* jSSC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jSSC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with jSSC. If not, see .
*
* If you use jSSC in public project you can inform me about this by e-mail,
* of course if you want it.
*
* e-mail: scream3r.org@gmail.com
* web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/
*/
package jssc;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
/**
*
* @author scream3r
*/
public class SerialPort {
private SerialNativeInterface serialInterface;
private SerialPortEventListener eventListener;
private long portHandle;
private String portName;
private boolean portOpened = false;
private boolean maskAssigned = false;
private boolean eventListenerAdded = false;
//since 2.2.0 ->
private Method methodErrorOccurred = null;
//<- since 2.2.0
public static final int BAUDRATE_110 = 110;
public static final int BAUDRATE_300 = 300;
public static final int BAUDRATE_600 = 600;
public static final int BAUDRATE_1200 = 1200;
public static final int BAUDRATE_4800 = 4800;
public static final int BAUDRATE_9600 = 9600;
public static final int BAUDRATE_14400 = 14400;
public static final int BAUDRATE_19200 = 19200;
public static final int BAUDRATE_38400 = 38400;
public static final int BAUDRATE_57600 = 57600;
public static final int BAUDRATE_115200 = 115200;
public static final int BAUDRATE_128000 = 128000;
public static final int BAUDRATE_256000 = 256000;
public static final int DATABITS_5 = 5;
public static final int DATABITS_6 = 6;
public static final int DATABITS_7 = 7;
public static final int DATABITS_8 = 8;
public static final int STOPBITS_1 = 1;
public static final int STOPBITS_2 = 2;
public static final int STOPBITS_1_5 = 3;
public static final int PARITY_NONE = 0;
public static final int PARITY_ODD = 1;
public static final int PARITY_EVEN = 2;
public static final int PARITY_MARK = 3;
public static final int PARITY_SPACE = 4;
public static final int PURGE_RXABORT = 0x0002;
public static final int PURGE_RXCLEAR = 0x0008;
public static final int PURGE_TXABORT = 0x0001;
public static final int PURGE_TXCLEAR = 0x0004;
public static final int MASK_RXCHAR = 1;
public static final int MASK_RXFLAG = 2;
public static final int MASK_TXEMPTY = 4;
public static final int MASK_CTS = 8;
public static final int MASK_DSR = 16;
public static final int MASK_RLSD = 32;
public static final int MASK_BREAK = 64;
public static final int MASK_ERR = 128;
public static final int MASK_RING = 256;
//since 0.8 ->
public static final int FLOWCONTROL_NONE = 0;
public static final int FLOWCONTROL_RTSCTS_IN = 1;
public static final int FLOWCONTROL_RTSCTS_OUT = 2;
public static final int FLOWCONTROL_XONXOFF_IN = 4;
public static final int FLOWCONTROL_XONXOFF_OUT = 8;
//<- since 0.8
//since 0.8 ->
public static final int ERROR_FRAME = 0x0008;
public static final int ERROR_OVERRUN = 0x0002;
public static final int ERROR_PARITY = 0x0004;
//<- since 0.8
//since 2.6.0 ->
private static final int PARAMS_FLAG_IGNPAR = 1;
private static final int PARAMS_FLAG_PARMRK = 2;
//<- since 2.6.0
public SerialPort(String portName) {
this.portName = portName;
serialInterface = new SerialNativeInterface();
}
/**
* Getting port name under operation
*
* @return Method returns port name under operation as a String
*/
public String getPortName(){
return portName;
}
/**
* Getting port state
*
* @return Method returns true if port is open, otherwise false
*/
public boolean isOpened() {
return portOpened;
}
/**
* Port opening
*
* Note: If port busy TYPE_PORT_BUSY exception will be thrown.
* If port not found TYPE_PORT_NOT_FOUND exception will be thrown.
*
* @return If the operation is successfully completed, the method returns true
*
* @throws SerialPortException
*/
public boolean openPort() throws SerialPortException {
if(portOpened){
throw new SerialPortException(portName, "openPort()", SerialPortException.TYPE_PORT_ALREADY_OPENED);
}
if(portName != null){
boolean useTIOCEXCL = (System.getProperty(SerialNativeInterface.PROPERTY_JSSC_NO_TIOCEXCL) == null &&
System.getProperty(SerialNativeInterface.PROPERTY_JSSC_NO_TIOCEXCL.toLowerCase()) == null);
portHandle = serialInterface.openPort(portName, useTIOCEXCL);//since 2.3.0 -> (if JSSC_NO_TIOCEXCL defined, exclusive lock for serial port will be disabled)
}
else {
throw new SerialPortException(portName, "openPort()", SerialPortException.TYPE_NULL_NOT_PERMITTED);//since 2.1.0 -> NULL port name fix
}
if(portHandle == SerialNativeInterface.ERR_PORT_BUSY){
throw new SerialPortException(portName, "openPort()", SerialPortException.TYPE_PORT_BUSY);
}
else if(portHandle == SerialNativeInterface.ERR_PORT_NOT_FOUND){
throw new SerialPortException(portName, "openPort()", SerialPortException.TYPE_PORT_NOT_FOUND);
}
else if(portHandle == SerialNativeInterface.ERR_PERMISSION_DENIED){
throw new SerialPortException(portName, "openPort()", SerialPortException.TYPE_PERMISSION_DENIED);
}
else if(portHandle == SerialNativeInterface.ERR_INCORRECT_SERIAL_PORT){
throw new SerialPortException(portName, "openPort()", SerialPortException.TYPE_INCORRECT_SERIAL_PORT);
}
portOpened = true;
return true;
}
/**
* Setting the parameters of port. RTS and DTR lines are enabled by default
*
* @param baudRate data transfer rate
* @param dataBits number of data bits
* @param stopBits number of stop bits
* @param parity parity
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*/
public boolean setParams(int baudRate, int dataBits, int stopBits, int parity) throws SerialPortException {
return setParams(baudRate, dataBits, stopBits, parity, true, true);
}
/**
* Setting the parameters of port
*
* @param baudRate data transfer rate
* @param dataBits number of data bits
* @param stopBits number of stop bits
* @param parity parity
* @param setRTS initial state of RTS line(ON/OFF)
* @param setDTR initial state of DTR line(ON/OFF)
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*
* @since 0.8
*/
public boolean setParams(int baudRate, int dataBits, int stopBits, int parity, boolean setRTS, boolean setDTR) throws SerialPortException {
checkPortOpened("setParams()");
if(stopBits == 1){
stopBits = 0;
}
else if(stopBits == 3){
stopBits = 1;
}
int flags = 0;
if(System.getProperty(SerialNativeInterface.PROPERTY_JSSC_IGNPAR) != null || System.getProperty(SerialNativeInterface.PROPERTY_JSSC_IGNPAR.toLowerCase()) != null){
flags |= PARAMS_FLAG_IGNPAR;
}
if(System.getProperty(SerialNativeInterface.PROPERTY_JSSC_PARMRK) != null || System.getProperty(SerialNativeInterface.PROPERTY_JSSC_PARMRK.toLowerCase()) != null){
flags |= PARAMS_FLAG_PARMRK;
}
return serialInterface.setParams(portHandle, baudRate, dataBits, stopBits, parity, setRTS, setDTR, flags);
}
/**
* Purge of input and output buffer. Required flags shall be sent to the input. Variables with prefix
* "PURGE_", for example "PURGE_RXCLEAR". Sent parameter "flags" is additive value,
* so addition of flags is allowed. For example, if input or output buffer shall be purged,
* parameter "PURGE_RXCLEAR | PURGE_TXCLEAR".
*
Note: some devices or drivers may not support this function
*
* @return If the operation is successfully completed, the method returns true, otherwise false.
*
* @throws SerialPortException
*/
public boolean purgePort(int flags) throws SerialPortException {
checkPortOpened("purgePort()");
return serialInterface.purgePort(portHandle, flags);
}
/**
* Events mask for Linux OS
*
* @since 0.8
*/
private int linuxMask;
/**
* Set events mask. Required flags shall be sent to the input. Variables with prefix
* "MASK_", shall be used as flags, for example "MASK_RXCHAR".
* Sent parameter "mask" is additive value, so addition of flags is allowed.
* For example if messages about data receipt and CTS and DSR status changing
* shall be received, it is required to set the mask - "MASK_RXCHAR | MASK_CTS | MASK_DSR"
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*/
public boolean setEventsMask(int mask) throws SerialPortException {
checkPortOpened("setEventsMask()");
if(SerialNativeInterface.getOsType() == SerialNativeInterface.OS_LINUX ||
SerialNativeInterface.getOsType() == SerialNativeInterface.OS_SOLARIS ||
SerialNativeInterface.getOsType() == SerialNativeInterface.OS_MAC_OS_X){//since 0.9.0
linuxMask = mask;
if(mask > 0){
maskAssigned = true;
}
else {
maskAssigned = false;
}
return true;
}
boolean returnValue = serialInterface.setEventsMask(portHandle, mask);
if(!returnValue){
throw new SerialPortException(portName, "setEventsMask()", SerialPortException.TYPE_CANT_SET_MASK);
}
if(mask > 0){
maskAssigned = true;
}
else {
maskAssigned = false;
}
return returnValue;
}
/**
* Getting events mask for the port
*
* @return Method returns events mask as int type variable. This variable is an additive value
*
* @throws SerialPortException
*/
public int getEventsMask() throws SerialPortException {
checkPortOpened("getEventsMask()");
if(SerialNativeInterface.getOsType() == SerialNativeInterface.OS_LINUX ||
SerialNativeInterface.getOsType() == SerialNativeInterface.OS_SOLARIS ||
SerialNativeInterface.getOsType() == SerialNativeInterface.OS_MAC_OS_X){//since 0.9.0
return linuxMask;
}
return serialInterface.getEventsMask(portHandle);
}
/**
* Getting events mask for the port is Linux OS (for internal use)
*
* @since 0.8
*/
private int getLinuxMask() {
return linuxMask;
}
/**
* Change RTS line state. Set "true" for switching ON and "false" for switching OFF RTS line
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*/
public boolean setRTS(boolean enabled) throws SerialPortException {
checkPortOpened("setRTS()");
return serialInterface.setRTS(portHandle, enabled);
}
/**
* Change DTR line state. Set "true" for switching ON and "false" for switching OFF DTR line
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*/
public boolean setDTR(boolean enabled) throws SerialPortException {
checkPortOpened("setDTR()");
return serialInterface.setDTR(portHandle, enabled);
}
/**
* Write byte array to port
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*/
public boolean writeBytes(byte[] buffer) throws SerialPortException {
checkPortOpened("writeBytes()");
return serialInterface.writeBytes(portHandle, buffer);
}
/**
* Write single byte to port
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*
* @since 0.8
*/
public boolean writeByte(byte singleByte) throws SerialPortException {
checkPortOpened("writeByte()");
return writeBytes(new byte[]{singleByte});
}
/**
* Write String to port
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*
* @since 0.8
*/
public boolean writeString(String string) throws SerialPortException {
checkPortOpened("writeString()");
return writeBytes(string.getBytes());
}
/**
* Write String to port
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*
* @since 2.8.0
*/
public boolean writeString(String string, String charsetName) throws SerialPortException, UnsupportedEncodingException {
checkPortOpened("writeString()");
return writeBytes(string.getBytes(charsetName));
}
/**
* Write int value (in range from 0 to 255 (0x00 - 0xFF)) to port
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*
* @since 0.8
*/
public boolean writeInt(int singleInt) throws SerialPortException {
checkPortOpened("writeInt()");
return writeBytes(new byte[]{(byte)singleInt});
}
/**
* Write int array (in range from 0 to 255 (0x00 - 0xFF)) to port
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*
* @since 0.8
*/
public boolean writeIntArray(int[] buffer) throws SerialPortException {
checkPortOpened("writeIntArray()");
byte[] byteArray = new byte[buffer.length];
for(int i = 0; i < buffer.length; i++){
byteArray[i] = (byte)buffer[i];
}
return writeBytes(byteArray);
}
/**
* Read byte array from port
*
* @param byteCount count of bytes for reading
*
* @return byte array with "byteCount" length
*
* @throws SerialPortException
*/
public byte[] readBytes(int byteCount) throws SerialPortException {
checkPortOpened("readBytes()");
return serialInterface.readBytes(portHandle, byteCount);
}
/**
* Read string from port
*
* @param byteCount count of bytes for reading
*
* @return byte array with "byteCount" length converted to String
*
* @throws SerialPortException
*
* @since 0.8
*/
public String readString(int byteCount) throws SerialPortException {
checkPortOpened("readString()");
return new String(readBytes(byteCount));
}
/**
* Read Hex string from port (example: FF 0A FF). Separator by default is a space
*
* @param byteCount count of bytes for reading
*
* @return byte array with "byteCount" length converted to Hexadecimal String
*
* @throws SerialPortException
*
* @since 0.8
*/
public String readHexString(int byteCount) throws SerialPortException {
checkPortOpened("readHexString()");
return readHexString(byteCount, " ");
}
/**
* Read Hex string from port with setted separator (example if separator is "::": FF::0A::FF)
*
* @param byteCount count of bytes for reading
*
* @return byte array with "byteCount" length converted to Hexadecimal String
*
* @throws SerialPortException
*
* @since 0.8
*/
public String readHexString(int byteCount, String separator) throws SerialPortException {
checkPortOpened("readHexString()");
String[] strBuffer = readHexStringArray(byteCount);
String returnString = "";
boolean insertSeparator = false;
for(String value : strBuffer){
if(insertSeparator){
returnString += separator;
}
returnString += value;
insertSeparator = true;
}
return returnString;
}
/**
* Read Hex String array from port
*
* @param byteCount count of bytes for reading
*
* @return String array with "byteCount" length and Hexadecimal String values
*
* @throws SerialPortException
*
* @since 0.8
*/
public String[] readHexStringArray(int byteCount) throws SerialPortException {
checkPortOpened("readHexStringArray()");
int[] intBuffer = readIntArray(byteCount);
String[] strBuffer = new String[intBuffer.length];
for(int i = 0; i < intBuffer.length; i++){
String value = Integer.toHexString(intBuffer[i]).toUpperCase();
if(value.length() == 1) {
value = "0" + value;
}
strBuffer[i] = value;
}
return strBuffer;
}
/**
* Read int array from port
*
* @param byteCount count of bytes for reading
*
* @return int array with values in range from 0 to 255
*
* @throws SerialPortException
*
* @since 0.8
*/
public int[] readIntArray(int byteCount) throws SerialPortException {
checkPortOpened("readIntArray()");
byte[] buffer = readBytes(byteCount);
int[] intBuffer = new int[buffer.length];
for(int i = 0; i < buffer.length; i++){
if(buffer[i] < 0){
intBuffer[i] = 256 + buffer[i];
}
else {
intBuffer[i] = buffer[i];
}
}
return intBuffer;
}
private void waitBytesWithTimeout(String methodName, int byteCount, int timeout) throws SerialPortException, SerialPortTimeoutException {
checkPortOpened("waitBytesWithTimeout()");
boolean timeIsOut = true;
long startTime = System.currentTimeMillis();
while((System.currentTimeMillis() - startTime) < timeout){
if(getInputBufferBytesCount() >= byteCount){
timeIsOut = false;
break;
}
try {
Thread.sleep(0, 100);//Need to sleep some time to prevent high CPU loading
}
catch (InterruptedException ex) {
//Do nothing
}
}
if(timeIsOut){
throw new SerialPortTimeoutException(portName, methodName, timeout);
}
}
/**
* Read byte array from port
*
* @param byteCount count of bytes for reading
* @param timeout timeout in milliseconds
*
* @return byte array with "byteCount" length
*
* @throws SerialPortException
* @throws SerialPortTimeoutException
*
* @since 2.0
*/
public byte[] readBytes(int byteCount, int timeout) throws SerialPortException, SerialPortTimeoutException {
checkPortOpened("readBytes()");
waitBytesWithTimeout("readBytes()", byteCount, timeout);
return readBytes(byteCount);
}
/**
* Read string from port
*
* @param byteCount count of bytes for reading
* @param timeout timeout in milliseconds
*
* @return byte array with "byteCount" length converted to String
*
* @throws SerialPortException
* @throws SerialPortTimeoutException
*
* @since 2.0
*/
public String readString(int byteCount, int timeout) throws SerialPortException, SerialPortTimeoutException {
checkPortOpened("readString()");
waitBytesWithTimeout("readString()", byteCount, timeout);
return readString(byteCount);
}
/**
* Read Hex string from port (example: FF 0A FF). Separator by default is a space
*
* @param byteCount count of bytes for reading
* @param timeout timeout in milliseconds
*
* @return byte array with "byteCount" length converted to Hexadecimal String
*
* @throws SerialPortException
* @throws SerialPortTimeoutException
*
* @since 2.0
*/
public String readHexString(int byteCount, int timeout) throws SerialPortException, SerialPortTimeoutException {
checkPortOpened("readHexString()");
waitBytesWithTimeout("readHexString()", byteCount, timeout);
return readHexString(byteCount);
}
/**
* Read Hex string from port with setted separator (example if separator is "::": FF::0A::FF)
*
* @param byteCount count of bytes for reading
* @param timeout timeout in milliseconds
*
* @return byte array with "byteCount" length converted to Hexadecimal String
*
* @throws SerialPortException
* @throws SerialPortTimeoutException
*
* @since 2.0
*/
public String readHexString(int byteCount, String separator, int timeout) throws SerialPortException, SerialPortTimeoutException {
checkPortOpened("readHexString()");
waitBytesWithTimeout("readHexString()", byteCount, timeout);
return readHexString(byteCount, separator);
}
/**
* Read Hex String array from port
*
* @param byteCount count of bytes for reading
* @param timeout timeout in milliseconds
*
* @return String array with "byteCount" length and Hexadecimal String values
*
* @throws SerialPortException
* @throws SerialPortTimeoutException
*
* @since 2.0
*/
public String[] readHexStringArray(int byteCount, int timeout) throws SerialPortException, SerialPortTimeoutException {
checkPortOpened("readHexStringArray()");
waitBytesWithTimeout("readHexStringArray()", byteCount, timeout);
return readHexStringArray(byteCount);
}
/**
* Read int array from port
*
* @param byteCount count of bytes for reading
* @param timeout timeout in milliseconds
*
* @return int array with values in range from 0 to 255
*
* @throws SerialPortException
* @throws SerialPortTimeoutException
*
* @since 2.0
*/
public int[] readIntArray(int byteCount, int timeout) throws SerialPortException, SerialPortTimeoutException {
checkPortOpened("readIntArray()");
waitBytesWithTimeout("readIntArray()", byteCount, timeout);
return readIntArray(byteCount);
}
/**
* Read all available bytes from port like a byte array
*
* @return If input buffer is empty null will be returned, else byte array with all data from port
*
* @throws SerialPortException
*
* @since 0.8
*/
public byte[] readBytes() throws SerialPortException {
checkPortOpened("readBytes()");
int byteCount = getInputBufferBytesCount();
if(byteCount <= 0){
return null;
}
return readBytes(byteCount);
}
/**
* Read all available bytes from port like a String
*
* @return If input buffer is empty null will be returned, else byte array with all data from port converted to String
*
* @throws SerialPortException
*
* @since 0.8
*/
public String readString() throws SerialPortException {
checkPortOpened("readString()");
int byteCount = getInputBufferBytesCount();
if(byteCount <= 0){
return null;
}
return readString(byteCount);
}
/**
* Read all available bytes from port like a Hex String
*
* @return If input buffer is empty null will be returned, else byte array with all data from port converted to Hex String
*
* @throws SerialPortException
*
* @since 0.8
*/
public String readHexString() throws SerialPortException {
checkPortOpened("readHexString()");
int byteCount = getInputBufferBytesCount();
if(byteCount <= 0){
return null;
}
return readHexString(byteCount);
}
/**
* Read all available bytes from port like a Hex String with setted separator
*
* @return If input buffer is empty null will be returned, else byte array with all data from port converted to Hex String
*
* @throws SerialPortException
*
* @since 0.8
*/
public String readHexString(String separator) throws SerialPortException {
checkPortOpened("readHexString()");
int byteCount = getInputBufferBytesCount();
if(byteCount <= 0){
return null;
}
return readHexString(byteCount, separator);
}
/**
* Read all available bytes from port like a Hex String array
*
* @return If input buffer is empty null will be returned, else byte array with all data from port converted to Hex String array
*
* @throws SerialPortException
*
* @since 0.8
*/
public String[] readHexStringArray() throws SerialPortException {
checkPortOpened("readHexStringArray()");
int byteCount = getInputBufferBytesCount();
if(byteCount <= 0){
return null;
}
return readHexStringArray(byteCount);
}
/**
* Read all available bytes from port like a int array (values in range from 0 to 255)
*
* @return If input buffer is empty null will be returned, else byte array with all data from port converted to int array
*
* @throws SerialPortException
*
* @since 0.8
*/
public int[] readIntArray() throws SerialPortException {
checkPortOpened("readIntArray()");
int byteCount = getInputBufferBytesCount();
if(byteCount <= 0){
return null;
}
return readIntArray(byteCount);
}
/**
* Get count of bytes in input buffer
*
* @return Count of bytes in input buffer or -1 if error occured
*
* @throws SerialPortException
*
* @since 0.8
*/
public int getInputBufferBytesCount() throws SerialPortException {
checkPortOpened("getInputBufferBytesCount()");
return serialInterface.getBuffersBytesCount(portHandle)[0];
}
/**
* Get count of bytes in output buffer
*
* @return Count of bytes in output buffer or -1 if error occured
*
* @throws SerialPortException
*
* @since 0.8
*/
public int getOutputBufferBytesCount() throws SerialPortException {
checkPortOpened("getOutputBufferBytesCount()");
return serialInterface.getBuffersBytesCount(portHandle)[1];
}
/**
* Set flow control mode. For required mode use variables with prefix "FLOWCONTROL_".
* Example of hardware flow control mode(RTS/CTS): setFlowControlMode(FLOWCONTROL_RTSCTS_IN | FLOWCONTROL_RTSCTS_OUT);
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*
* @since 0.8
*/
public boolean setFlowControlMode(int mask) throws SerialPortException {
checkPortOpened("setFlowControlMode()");
return serialInterface.setFlowControlMode(portHandle, mask);
}
/**
* Get flow control mode
*
* @return Mask of setted flow control mode
*
* @throws SerialPortException
*
* @since 0.8
*/
public int getFlowControlMode() throws SerialPortException {
checkPortOpened("getFlowControlMode()");
return serialInterface.getFlowControlMode(portHandle);
}
/**
* Send Break singnal for setted duration
*
* @param duration duration of Break signal
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*
* @since 0.8
*/
public boolean sendBreak(int duration)throws SerialPortException {
checkPortOpened("sendBreak()");
return serialInterface.sendBreak(portHandle, duration);
}
private int[][] waitEvents() {
return serialInterface.waitEvents(portHandle);
}
/**
* Check port opened (since jSSC-0.8 String "EMPTY" was replaced with "portName" variable)
*
* @param methodName method name
*
* @throws SerialPortException
*/
private void checkPortOpened(String methodName) throws SerialPortException {
if(!portOpened){
throw new SerialPortException(portName, methodName, SerialPortException.TYPE_PORT_NOT_OPENED);
}
}
/**
* Getting lines status. Lines status is sent as 0 – OFF and 1 - ON
*
* @return Method returns the array containing information about lines in following order:
*
element 0 - CTS line state
*
element 1 - DSR line state
*
element 2 - RING line state
*
element 3 - RLSD line state
*
* @throws SerialPortException
*/
public int[] getLinesStatus() throws SerialPortException {
checkPortOpened("getLinesStatus()");
return serialInterface.getLinesStatus(portHandle);
}
/**
* Get state of CTS line
*
* @return If line is active, method returns true, otherwise false
*
* @throws SerialPortException
*/
public boolean isCTS() throws SerialPortException {
checkPortOpened("isCTS()");
if(serialInterface.getLinesStatus(portHandle)[0] == 1){
return true;
}
else {
return false;
}
}
/**
* Get state of DSR line
*
* @return If line is active, method returns true, otherwise false
*
* @throws SerialPortException
*/
public boolean isDSR() throws SerialPortException {
checkPortOpened("isDSR()");
if(serialInterface.getLinesStatus(portHandle)[1] == 1){
return true;
}
else {
return false;
}
}
/**
* Get state of RING line
*
* @return If line is active, method returns true, otherwise false
*
* @throws SerialPortException
*/
public boolean isRING() throws SerialPortException {
checkPortOpened("isRING()");
if(serialInterface.getLinesStatus(portHandle)[2] == 1){
return true;
}
else {
return false;
}
}
/**
* Get state of RLSD line
*
* @return If line is active, method returns true, otherwise false
*
* @throws SerialPortException
*/
public boolean isRLSD() throws SerialPortException {
checkPortOpened("isRLSD()");
if(serialInterface.getLinesStatus(portHandle)[3] == 1){
return true;
}
else {
return false;
}
}
/**
* Add event listener. Object of "SerialPortEventListener" type shall
* be sent to the method. This object shall be properly described, as it will
* be in charge for handling of occurred events. This method will independently
* set the mask in "MASK_RXCHAR" state if it was not set beforehand
*
* @throws SerialPortException
*/
public void addEventListener(SerialPortEventListener listener) throws SerialPortException {
addEventListener(listener, MASK_RXCHAR, false);
}
/**
* Add event listener. Object of "SerialPortEventListener" type shall be sent
* to the method. This object shall be properly described, as it will be in
* charge for handling of occurred events. Also events mask shall be sent to
* this method, to do it use variables with prefix "MASK_" for example "MASK_RXCHAR"
*
* @see #setEventsMask(int) setEventsMask(int mask)
*
* @throws SerialPortException
*/
public void addEventListener(SerialPortEventListener listener, int mask) throws SerialPortException {
addEventListener(listener, mask, true);
}
/**
* Internal method. Add event listener. Object of "SerialPortEventListener" type shall be sent
* to the method. This object shall be properly described, as it will be in
* charge for handling of occurred events. Also events mask shall be sent to
* this method, to do it use variables with prefix "MASK_" for example "MASK_RXCHAR". If
* overwriteMask == true and mask has been already assigned it value will be rewrited by mask
* value, if overwriteMask == false and mask has been already assigned the new mask value will be ignored,
* if there is no assigned mask to this serial port the mask value will be used for setting it up in spite of
* overwriteMask value
*
* @see #setEventsMask(int) setEventsMask(int mask)
*
* @throws SerialPortException
*/
private void addEventListener(SerialPortEventListener listener, int mask, boolean overwriteMask) throws SerialPortException {
checkPortOpened("addEventListener()");
if(!eventListenerAdded){
if((maskAssigned && overwriteMask) || !maskAssigned) {
setEventsMask(mask);
}
eventListener = listener;
eventThread = getNewEventThread();
eventThread.setName("EventThread " + portName);
//since 2.2.0 ->
try {
Method method = eventListener.getClass().getMethod("errorOccurred", new Class[]{SerialPortException.class});
method.setAccessible(true);
methodErrorOccurred = method;
}
catch (SecurityException ex) {
//Do nothing
}
catch (NoSuchMethodException ex) {
//Do nothing
}
//<- since 2.2.0
eventThread.start();
eventListenerAdded = true;
}
else {
throw new SerialPortException(portName, "addEventListener()", SerialPortException.TYPE_LISTENER_ALREADY_ADDED);
}
}
/**
* Create new EventListener Thread depending on the type of operating system
*
* @since 0.8
*/
private EventThread getNewEventThread() {
if(SerialNativeInterface.getOsType() == SerialNativeInterface.OS_LINUX ||
SerialNativeInterface.getOsType() == SerialNativeInterface.OS_SOLARIS ||
SerialNativeInterface.getOsType() == SerialNativeInterface.OS_MAC_OS_X){//since 0.9.0
return new LinuxEventThread();
}
return new EventThread();
}
/**
* Delete event listener. Mask is set to 0. So at the next addition of event
* handler you shall set required event mask again
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*/
public boolean removeEventListener() throws SerialPortException {
checkPortOpened("removeEventListener()");
if(!eventListenerAdded){
throw new SerialPortException(portName, "removeEventListener()", SerialPortException.TYPE_CANT_REMOVE_LISTENER);
}
eventThread.terminateThread();
setEventsMask(0);
if(Thread.currentThread().getId() != eventThread.getId()){
if(eventThread.isAlive()){
try {
eventThread.join(5000);
}
catch (InterruptedException ex) {
throw new SerialPortException(portName, "removeEventListener()", SerialPortException.TYPE_LISTENER_THREAD_INTERRUPTED);
}
}
}
methodErrorOccurred = null;
eventListenerAdded = false;
return true;
}
/**
* Close port. This method deletes event listener first, then closes the port
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException
*/
public boolean closePort() throws SerialPortException {
checkPortOpened("closePort()");
if(eventListenerAdded){
removeEventListener();
}
boolean returnValue = serialInterface.closePort(portHandle);
if(returnValue){
maskAssigned = false;
portOpened = false;
}
return returnValue;
}
private EventThread eventThread;
private class EventThread extends Thread {
private boolean threadTerminated = false;
@Override
public void run() {
while(!threadTerminated){
int[][] eventArray = waitEvents();
for(int i = 0; i < eventArray.length; i++){
if(eventArray[i][0] > 0 && !threadTerminated){
eventListener.serialEvent(new SerialPortEvent(portName, eventArray[i][0], eventArray[i][1]));
//FIXME
/*if(methodErrorOccurred != null){
try {
methodErrorOccurred.invoke(eventListener, new Object[]{new SerialPortException("port", "method", "exception")});
}
catch (Exception ex) {
System.out.println(ex);
}
}*/
}
}
}
}
private void terminateThread(){
threadTerminated = true;
}
}
/**
* EventListener for Linux OS
*
* @since 0.8
*/
private class LinuxEventThread extends EventThread {
//Essential interruptions for events: BREAK, ERR, TXEMPTY
private final int INTERRUPT_BREAK = 512;
private final int INTERRUPT_TX = 1024;
private final int INTERRUPT_FRAME = 2048;
private final int INTERRUPT_OVERRUN = 4096;
private final int INTERRUPT_PARITY = 8192;
//Count of interruptions
private int interruptBreak;
private int interruptTX;
private int interruptFrame;
private int interruptOverrun;
private int interruptParity;
//Previous states if lines (then state change event will be generated)
private int preCTS;
private int preDSR;
private int preRLSD;
private int preRING;
//Need to get initial states
public LinuxEventThread(){
int[][] eventArray = waitEvents();
for(int i = 0; i < eventArray.length; i++){
int eventType = eventArray[i][0];
int eventValue = eventArray[i][1];
switch(eventType){
case INTERRUPT_BREAK:
interruptBreak = eventValue;
break;
case INTERRUPT_TX:
interruptTX = eventValue;
break;
case INTERRUPT_FRAME:
interruptFrame = eventValue;
break;
case INTERRUPT_OVERRUN:
interruptOverrun = eventValue;
break;
case INTERRUPT_PARITY:
interruptParity = eventValue;
break;
case MASK_CTS:
preCTS = eventValue;
break;
case MASK_DSR:
preDSR = eventValue;
break;
case MASK_RING:
preRING = eventValue;
break;
case MASK_RLSD:
preRLSD = eventValue;
break;
}
}
}
@Override
public void run() {
while(!super.threadTerminated){
int[][] eventArray = waitEvents();
int mask = getLinuxMask();
boolean interruptTxChanged = false;
int errorMask = 0;
for(int i = 0; i < eventArray.length; i++){
boolean sendEvent = false;
int eventType = eventArray[i][0];
int eventValue = eventArray[i][1];
if(eventType > 0 && !super.threadTerminated){
switch(eventType){
case INTERRUPT_BREAK:
if(eventValue != interruptBreak){
interruptBreak = eventValue;
if((mask & MASK_BREAK) == MASK_BREAK){
eventType = MASK_BREAK;
eventValue = 0;
sendEvent = true;
}
}
break;
case INTERRUPT_TX:
if(eventValue != interruptTX){
interruptTX = eventValue;
interruptTxChanged = true;
}
break;
case INTERRUPT_FRAME:
if(eventValue != interruptFrame){
interruptFrame = eventValue;
errorMask |= ERROR_FRAME;
}
break;
case INTERRUPT_OVERRUN:
if(eventValue != interruptOverrun){
interruptOverrun = eventValue;
errorMask |= ERROR_OVERRUN;
}
break;
case INTERRUPT_PARITY:
if(eventValue != interruptParity){
interruptParity = eventValue;
errorMask |= ERROR_PARITY;
}
if((mask & MASK_ERR) == MASK_ERR && errorMask != 0){
eventType = MASK_ERR;
eventValue = errorMask;
sendEvent = true;
}
break;
case MASK_CTS:
if(eventValue != preCTS){
preCTS = eventValue;
if((mask & MASK_CTS) == MASK_CTS){
sendEvent = true;
}
}
break;
case MASK_DSR:
if(eventValue != preDSR){
preDSR = eventValue;
if((mask & MASK_DSR) == MASK_DSR){
sendEvent = true;
}
}
break;
case MASK_RING:
if(eventValue != preRING){
preRING = eventValue;
if((mask & MASK_RING) == MASK_RING){
sendEvent = true;
}
}
break;
case MASK_RLSD: /*DCD*/
if(eventValue != preRLSD){
preRLSD = eventValue;
if((mask & MASK_RLSD) == MASK_RLSD){
sendEvent = true;
}
}
break;
case MASK_RXCHAR:
if(((mask & MASK_RXCHAR) == MASK_RXCHAR) && (eventValue > 0)){
sendEvent = true;
}
break;
/*case MASK_RXFLAG:
//Do nothing at this moment
if(((mask & MASK_RXFLAG) == MASK_RXFLAG) && (eventValue > 0)){
sendEvent = true;
}
break;*/
case MASK_TXEMPTY:
if(((mask & MASK_TXEMPTY) == MASK_TXEMPTY) && (eventValue == 0) && interruptTxChanged){
sendEvent = true;
}
break;
}
if(sendEvent){
eventListener.serialEvent(new SerialPortEvent(portName, eventType, eventValue));
}
}
}
//Need to sleep some time
try {
Thread.sleep(0, 100);
}
catch (Exception ex) {
//Do nothing
}
}
}
}
}
java-simple-serial-connector-2.8.0/src/java/jssc/SerialPortEvent.java 0000664 0000000 0000000 00000011733 12270474732 0025616 0 ustar 00root root 0000000 0000000 /* jSSC (Java Simple Serial Connector) - serial port communication library.
* © Alexey Sokolov (scream3r), 2010-2014.
*
* This file is part of jSSC.
*
* jSSC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jSSC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with jSSC. If not, see .
*
* If you use jSSC in public project you can inform me about this by e-mail,
* of course if you want it.
*
* e-mail: scream3r.org@gmail.com
* web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/
*/
package jssc;
/**
*
* @author scream3r
*/
public class SerialPortEvent {
private String portName;
private int eventType;
private int eventValue;
public static final int RXCHAR = 1;
public static final int RXFLAG = 2;
public static final int TXEMPTY = 4;
public static final int CTS = 8;
public static final int DSR = 16;
public static final int RLSD = 32;
public static final int BREAK = 64;
public static final int ERR = 128;
public static final int RING = 256;
public SerialPortEvent(String portName, int eventType, int eventValue){
this.portName = portName;
this.eventType = eventType;
this.eventValue = eventValue;
}
/**
* Getting port name which sent the event
*/
public String getPortName() {
return portName;
}
/**
* Getting event type
*/
public int getEventType() {
return eventType;
}
/**
* Getting event value
*
*
Event values depending on their types:
*
RXCHAR - bytes count in input buffer
*
RXFLAG - bytes count in input buffer (Not supported in Linux)
*
TXEMPTY - bytes count in output buffer
*
CTS - state of CTS line (0 - OFF, 1 - ON)
*
DSR - state of DSR line (0 - OFF, 1 - ON)
*
RLSD - state of RLSD line (0 - OFF, 1 - ON)
*
BREAK - 0
*
RING - state of RING line (0 - OFF, 1 - ON)
*
ERR - mask of errors
*/
public int getEventValue() {
return eventValue;
}
/**
* Method returns true if event of type "RXCHAR" is received and otherwise false
*/
public boolean isRXCHAR() {
if(eventType == RXCHAR){
return true;
}
else {
return false;
}
}
/**
* Method returns true if event of type "RXFLAG" is received and otherwise false
*/
public boolean isRXFLAG() {
if(eventType == RXFLAG){
return true;
}
else {
return false;
}
}
/**
* Method returns true if event of type "TXEMPTY" is received and otherwise false
*/
public boolean isTXEMPTY() {
if(eventType == TXEMPTY){
return true;
}
else {
return false;
}
}
/**
* Method returns true if event of type "CTS" is received and otherwise false
*/
public boolean isCTS() {
if(eventType == CTS){
return true;
}
else {
return false;
}
}
/**
* Method returns true if event of type "DSR" is received and otherwise false
*/
public boolean isDSR() {
if(eventType == DSR){
return true;
}
else {
return false;
}
}
/**
* Method returns true if event of type "RLSD" is received and otherwise false
*/
public boolean isRLSD() {
if(eventType == RLSD){
return true;
}
else {
return false;
}
}
/**
* Method returns true if event of type "BREAK" is received and otherwise false
*/
public boolean isBREAK() {
if(eventType == BREAK){
return true;
}
else {
return false;
}
}
/**
* Method returns true if event of type "ERR" is received and otherwise false
*/
public boolean isERR() {
if(eventType == ERR){
return true;
}
else {
return false;
}
}
/**
* Method returns true if event of type "RING" is received and otherwise false
*/
public boolean isRING() {
if(eventType == RING){
return true;
}
else {
return false;
}
}
}
java-simple-serial-connector-2.8.0/src/java/jssc/SerialPortEventListener.java 0000664 0000000 0000000 00000002262 12270474732 0027321 0 ustar 00root root 0000000 0000000 /* jSSC (Java Simple Serial Connector) - serial port communication library.
* © Alexey Sokolov (scream3r), 2010-2014.
*
* This file is part of jSSC.
*
* jSSC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jSSC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with jSSC. If not, see .
*
* If you use jSSC in public project you can inform me about this by e-mail,
* of course if you want it.
*
* e-mail: scream3r.org@gmail.com
* web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/
*/
package jssc;
/**
*
* @author scream3r
*/
public interface SerialPortEventListener {
public abstract void serialEvent(SerialPortEvent serialPortEvent);
}
java-simple-serial-connector-2.8.0/src/java/jssc/SerialPortException.java 0000664 0000000 0000000 00000006234 12270474732 0026473 0 ustar 00root root 0000000 0000000 /* jSSC (Java Simple Serial Connector) - serial port communication library.
* © Alexey Sokolov (scream3r), 2010-2014.
*
* This file is part of jSSC.
*
* jSSC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jSSC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with jSSC. If not, see .
*
* If you use jSSC in public project you can inform me about this by e-mail,
* of course if you want it.
*
* e-mail: scream3r.org@gmail.com
* web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/
*/
package jssc;
/**
*
* @author scream3r
*/
public class SerialPortException extends Exception {
final public static String TYPE_PORT_ALREADY_OPENED = "Port already opened";
final public static String TYPE_PORT_NOT_OPENED = "Port not opened";
final public static String TYPE_CANT_SET_MASK = "Can't set mask";
final public static String TYPE_LISTENER_ALREADY_ADDED = "Event listener already added";
final public static String TYPE_LISTENER_THREAD_INTERRUPTED = "Event listener thread interrupted";
final public static String TYPE_CANT_REMOVE_LISTENER = "Can't remove event listener, because listener not added";
/**
* @since 0.8
*/
final public static String TYPE_PARAMETER_IS_NOT_CORRECT = "Parameter is not correct";
/**
* @since 0.8
*/
final public static String TYPE_NULL_NOT_PERMITTED = "Null not permitted";
/**
* @since 0.9.0
*/
final public static String TYPE_PORT_BUSY = "Port busy";
/**
* @since 0.9.0
*/
final public static String TYPE_PORT_NOT_FOUND = "Port not found";
/**
* @since 2.2.0
*/
final public static String TYPE_PERMISSION_DENIED = "Permission denied";
/**
* @since 2.3.0
*/
final public static String TYPE_INCORRECT_SERIAL_PORT = "Incorrect serial port";
private String portName;
private String methodName;
private String exceptionType;
public SerialPortException(String portName, String methodName, String exceptionType){
super("Port name - " + portName + "; Method name - " + methodName + "; Exception type - " + exceptionType + ".");
this.portName = portName;
this.methodName = methodName;
this.exceptionType = exceptionType;
}
/**
* Getting port name during operation with which the exception was called
*/
public String getPortName(){
return portName;
}
/**
* Getting method name during execution of which the exception was called
*/
public String getMethodName(){
return methodName;
}
/**
* Getting exception type
*/
public String getExceptionType(){
return exceptionType;
}
}
java-simple-serial-connector-2.8.0/src/java/jssc/SerialPortList.java 0000664 0000000 0000000 00000031642 12270474732 0025451 0 ustar 00root root 0000000 0000000 /* jSSC (Java Simple Serial Connector) - serial port communication library.
* © Alexey Sokolov (scream3r), 2010-2014.
*
* This file is part of jSSC.
*
* jSSC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jSSC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with jSSC. If not, see .
*
* If you use jSSC in public project you can inform me about this by e-mail,
* of course if you want it.
*
* e-mail: scream3r.org@gmail.com
* web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/
*/
package jssc;
import java.io.File;
import java.util.Comparator;
import java.util.TreeSet;
import java.util.regex.Pattern;
/**
*
* @author scream3r
*/
public class SerialPortList {
private static SerialNativeInterface serialInterface;
private static final Pattern PORTNAMES_REGEXP;
private static final String PORTNAMES_PATH;
static {
serialInterface = new SerialNativeInterface();
switch (SerialNativeInterface.getOsType()) {
case SerialNativeInterface.OS_LINUX: {
PORTNAMES_REGEXP = Pattern.compile("(ttyS|ttyUSB|ttyACM|ttyAMA|rfcomm|ttyO)[0-9]{1,3}");
PORTNAMES_PATH = "/dev/";
break;
}
case SerialNativeInterface.OS_SOLARIS: {
PORTNAMES_REGEXP = Pattern.compile("[0-9]*|[a-z]*");
PORTNAMES_PATH = "/dev/term/";
break;
}
case SerialNativeInterface.OS_MAC_OS_X: {
PORTNAMES_REGEXP = Pattern.compile("tty.(serial|usbserial|usbmodem).*");
PORTNAMES_PATH = "/dev/";
break;
}
case SerialNativeInterface.OS_WINDOWS: {
PORTNAMES_REGEXP = Pattern.compile("");
PORTNAMES_PATH = "";
break;
}
default: {
PORTNAMES_REGEXP = null;
PORTNAMES_PATH = null;
break;
}
}
}
//since 2.1.0 -> Fully rewrited port name comparator
private static final Comparator PORTNAMES_COMPARATOR = new Comparator() {
@Override
public int compare(String valueA, String valueB) {
if(valueA.equalsIgnoreCase(valueB)){
return valueA.compareTo(valueB);
}
int minLength = Math.min(valueA.length(), valueB.length());
int shiftA = 0;
int shiftB = 0;
for(int i = 0; i < minLength; i++){
char charA = valueA.charAt(i - shiftA);
char charB = valueB.charAt(i - shiftB);
if(charA != charB){
if(Character.isDigit(charA) && Character.isDigit(charB)){
int[] resultsA = getNumberAndLastIndex(valueA, i - shiftA);
int[] resultsB = getNumberAndLastIndex(valueB, i - shiftB);
if(resultsA[0] != resultsB[0]){
return resultsA[0] - resultsB[0];
}
if(valueA.length() < valueB.length()){
i = resultsA[1];
shiftB = resultsA[1] - resultsB[1];
}
else {
i = resultsB[1];
shiftA = resultsB[1] - resultsA[1];
}
}
else {
if(Character.toLowerCase(charA) - Character.toLowerCase(charB) != 0){
return Character.toLowerCase(charA) - Character.toLowerCase(charB);
}
}
}
}
return valueA.compareToIgnoreCase(valueB);
}
/**
* Evaluate port index/number from startIndex to the number end. For example:
* for port name serial-123-FF you should invoke this method with startIndex = 7
*
* @return If port index/number correctly evaluated it value will be returned
* returnArray[0] = index/number
* returnArray[1] = stopIndex
*
* If incorrect:
* returnArray[0] = -1
* returnArray[1] = startIndex
*
* For this name serial-123-FF result is:
* returnArray[0] = 123
* returnArray[1] = 10
*/
private int[] getNumberAndLastIndex(String str, int startIndex) {
String numberValue = "";
int[] returnValues = {-1, startIndex};
for(int i = startIndex; i < str.length(); i++){
returnValues[1] = i;
char c = str.charAt(i);
if(Character.isDigit(c)){
numberValue += c;
}
else {
break;
}
}
try {
returnValues[0] = Integer.valueOf(numberValue);
}
catch (Exception ex) {
//Do nothing
}
return returnValues;
}
};
//<-since 2.1.0
/**
* Get sorted array of serial ports in the system using default settings:
*
* Search path
* Windows - ""(always ignored)
* Linux - "/dev/"
* Solaris - "/dev/term/"
* MacOSX - "/dev/"
*
* RegExp
* Windows - ""
* Linux - "(ttyS|ttyUSB|ttyACM|ttyAMA|rfcomm)[0-9]{1,3}"
* Solaris - "[0-9]*|[a-z]*"
* MacOSX - "tty.(serial|usbserial|usbmodem).*"
*
* @return String array. If there is no ports in the system String[]
* with zero length will be returned (since jSSC-0.8 in previous versions null will be returned)
*/
public static String[] getPortNames() {
return getPortNames(PORTNAMES_PATH, PORTNAMES_REGEXP, PORTNAMES_COMPARATOR);
}
/**
* Get sorted array of serial ports in the system located on searchPath
*
* @param searchPath Path for searching serial ports (not null)
* The default search paths:
* Linux, MacOSX: /dev/
* Solaris: /dev/term/
* Windows: this parameter ingored
*
* @return String array. If there is no ports in the system String[]
*
* @since 2.3.0
*/
public static String[] getPortNames(String searchPath) {
return getPortNames(searchPath, PORTNAMES_REGEXP, PORTNAMES_COMPARATOR);
}
/**
* Get sorted array of serial ports in the system matched pattern
*
* @param pattern RegExp pattern for matching port names (not null)
*
* @return String array. If there is no ports in the system String[]
*
* @since 2.3.0
*/
public static String[] getPortNames(Pattern pattern) {
return getPortNames(PORTNAMES_PATH, pattern, PORTNAMES_COMPARATOR);
}
/**
* Get sorted array of serial ports in the system matched pattern
*
* @param comparator Comparator for sotring port names (not null)
*
* @return String array. If there is no ports in the system String[]
*
* @since 2.3.0
*/
public static String[] getPortNames(Comparator comparator) {
return getPortNames(PORTNAMES_PATH, PORTNAMES_REGEXP, comparator);
}
/**
* Get sorted array of serial ports in the system located on searchPath, matched pattern
*
* @param searchPath Path for searching serial ports (not null)
* The default search paths:
* Linux, MacOSX: /dev/
* Solaris: /dev/term/
* Windows: this parameter ingored
* @param pattern RegExp pattern for matching port names (not null)
*
* @return String array. If there is no ports in the system String[]
*
* @since 2.3.0
*/
public static String[] getPortNames(String searchPath, Pattern pattern) {
return getPortNames(searchPath, pattern, PORTNAMES_COMPARATOR);
}
/**
* Get sorted array of serial ports in the system located on searchPath and sorted by comparator
*
* @param searchPath Path for searching serial ports (not null)
* The default search paths:
* Linux, MacOSX: /dev/
* Solaris: /dev/term/
* Windows: this parameter ingored
* @param comparator Comparator for sotring port names (not null)
*
* @return String array. If there is no ports in the system String[]
*
* @since 2.3.0
*/
public static String[] getPortNames(String searchPath, Comparator comparator) {
return getPortNames(searchPath, PORTNAMES_REGEXP, comparator);
}
/**
* Get sorted array of serial ports in the system matched pattern and sorted by comparator
*
* @param pattern RegExp pattern for matching port names (not null)
* @param comparator Comparator for sotring port names (not null)
*
* @return String array. If there is no ports in the system String[]
*
* @since 2.3.0
*/
public static String[] getPortNames(Pattern pattern, Comparator comparator) {
return getPortNames(PORTNAMES_PATH, pattern, comparator);
}
/**
* Get sorted array of serial ports in the system located on searchPath, matched pattern and sorted by comparator
*
* @param searchPath Path for searching serial ports (not null)
* The default search paths:
* Linux, MacOSX: /dev/
* Solaris: /dev/term/
* Windows: this parameter ingored
* @param pattern RegExp pattern for matching port names (not null)
* @param comparator Comparator for sotring port names (not null)
*
* @return String array. If there is no ports in the system String[]
*
* @since 2.3.0
*/
public static String[] getPortNames(String searchPath, Pattern pattern, Comparator comparator) {
if(searchPath == null || pattern == null || comparator == null){
return new String[]{};
}
if(SerialNativeInterface.getOsType() == SerialNativeInterface.OS_WINDOWS){
return getWindowsPortNames(pattern, comparator);
}
return getUnixBasedPortNames(searchPath, pattern, comparator);
}
/**
* Get serial port names in Windows
*
* @since 2.3.0
*/
private static String[] getWindowsPortNames(Pattern pattern, Comparator comparator) {
String[] portNames = serialInterface.getSerialPortNames();
if(portNames == null){
return new String[]{};
}
TreeSet ports = new TreeSet(comparator);
for(String portName : portNames){
if(pattern.matcher(portName).find()){
ports.add(portName);
}
}
return ports.toArray(new String[ports.size()]);
}
/**
* Universal method for getting port names of _nix based systems
*/
private static String[] getUnixBasedPortNames(String searchPath, Pattern pattern, Comparator comparator) {
searchPath = (searchPath.equals("") ? searchPath : (searchPath.endsWith("/") ? searchPath : searchPath + "/"));
String[] returnArray = new String[]{};
File dir = new File(searchPath);
if(dir.exists() && dir.isDirectory()){
File[] files = dir.listFiles();
if(files.length > 0){
TreeSet portsTree = new TreeSet(comparator);
for(File file : files){
String fileName = file.getName();
if(!file.isDirectory() && !file.isFile() && pattern.matcher(fileName).find()){
String portName = searchPath + fileName;
long portHandle = serialInterface.openPort(portName, false);//Open port without TIOCEXCL
if(portHandle < 0 && portHandle != SerialNativeInterface.ERR_PORT_BUSY){
continue;
}
else if(portHandle != SerialNativeInterface.ERR_PORT_BUSY) {
serialInterface.closePort(portHandle);
}
portsTree.add(portName);
}
}
returnArray = portsTree.toArray(returnArray);
}
}
return returnArray;
}
}
java-simple-serial-connector-2.8.0/src/java/jssc/SerialPortTimeoutException.java 0000664 0000000 0000000 00000003774 12270474732 0030050 0 ustar 00root root 0000000 0000000 /* jSSC (Java Simple Serial Connector) - serial port communication library.
* © Alexey Sokolov (scream3r), 2010-2014.
*
* This file is part of jSSC.
*
* jSSC is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* jSSC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with jSSC. If not, see .
*
* If you use jSSC in public project you can inform me about this by e-mail,
* of course if you want it.
*
* e-mail: scream3r.org@gmail.com
* web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/
*/
package jssc;
/**
*
* @author scream3r
*/
public class SerialPortTimeoutException extends Exception {
private String portName;
private String methodName;
private int timeoutValue;
public SerialPortTimeoutException(String portName, String methodName, int timeoutValue) {
super("Port name - " + portName + "; Method name - " + methodName + "; Serial port operation timeout (" + timeoutValue + " ms).");
this.portName = portName;
this.methodName = methodName;
this.timeoutValue = timeoutValue;
}
/**
* Getting port name during operation with which the exception was called
*/
public String getPortName(){
return portName;
}
/**
* Getting method name during execution of which the exception was called
*/
public String getMethodName(){
return methodName;
}
/**
* Getting timeout value in millisecond
*/
public int getTimeoutValue(){
return timeoutValue;
}
}
java-simple-serial-connector-2.8.0/src/java/libs/ 0000775 0000000 0000000 00000000000 12270474732 0021647 5 ustar 00root root 0000000 0000000 java-simple-serial-connector-2.8.0/src/java/libs/linux/ 0000775 0000000 0000000 00000000000 12270474732 0023006 5 ustar 00root root 0000000 0000000 java-simple-serial-connector-2.8.0/src/java/libs/linux/libjSSC-2.8_armhf.so 0000664 0000000 0000000 00000024607 12270474732 0026335 0 ustar 00root root 0000000 0000000 ELF ( d 4 $ 4 ( p! ! ! " " " ," , , $ $ Qtd GNU ڐ}sK#% : ' 3 6 " / 4 ( ) . #
* &