gnu.io.RXTXPort Maven / Gradle / Ivy
/*
* Copyright 1997-2009 by Trent Jarvi and others
* Copyright 1998 Kevin Hester, [email protected]
* Copyright 2016 Fraunhofer ISE and others
*
* This file is part of jRxTx.
* jRxTx is a fork of RXTX originally maintained by Trent Jarvi.
*
* jRxTx is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* jRxTx 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 jRxTx. If not, see .
*
*/
package gnu.io;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.TooManyListenersException;
import gnu.io.SerialPortEvent.EventType;
import gnu.io.serialport.DataBits;
import gnu.io.serialport.FlowControl;
import gnu.io.serialport.Parity;
import gnu.io.serialport.StopBits;
import gnu.io.serialport.UARTType;
public class RXTXPort extends SerialPort {
static {
System.loadLibrary("rxtxSerial");
Initialize();
}
@Deprecated
private final SerialInputStream is;
@Deprecated
private final SerialOutputStream os;
private final InputStream serialIS;
/* dont close the file while accessing the fd */
private int IOLocked = 0;
private final Object IOLockedMutex = new Object();
private int fd = 0;
private boolean MonitorThreadAlive = false;
private int dataBits = DataBits.DATABITS_8.value();
private int speed = 9600;
private int stopBits = StopBits.STOPBITS_1.value();
private int parity = Parity.NONE.value();
private int flowmode = FlowControl.NONE.value();
private int timeout = -1;
private int threshold = 0;
private volatile boolean closed;
/**
* a pointer to the event info structure used to share information between threads so write threads can send output
* buffer empty from a pthread if need be.
*
* long for 64 bit pointers.
*/
long eis = 0;
/** pid for lock files */
int pid = 0;
static boolean dsrFlag = false;
private int InputBuffer = 0;
private int OutputBuffer = 0;
private SerialPortEventListener serialPortEventListener;
private MonitorThread monThread;
boolean MonitorThreadLock = true;
/**
* @return boolean true if monitor thread is interrupted
*/
boolean monThreadisInterrupted = true;
/**
* Open the named port.
*
* @param name
* the name of the device to open
* @throws PortInUseException
* if the file is already locked by an other application.
*/
public RXTXPort(String name) throws PortInUseException {
fd = open(name);
this.name = name;
MonitorThreadLock = true;
monThread = new MonitorThread();
monThread.start();
waitForTheNativeCodeSilly();
MonitorThreadAlive = true;
this.is = new SerialInputStream();
this.os = new SerialOutputStream();
this.serialIS = new BetterSerialInputStream(is);
this.closed = false;
}
@Override
public OutputStream getOutputStream() {
return os;
}
@Override
public InputStream getInputStream() {
return is;
}
@Override
public OutputStream outputStream() {
return os; // TODO
}
@Override
public InputStream inputStream() {
return this.serialIS;
}
private native static void Initialize();
private native synchronized int open(String name) throws PortInUseException;
private native int nativeGetParity(int fd);
private native int nativeGetFlowControlMode(int fd);
native void setflowcontrol(int flowcontrol) throws IOException;
/**
* @return int the timeout
*/
public native int NativegetReceiveTimeout();
private native boolean NativeisReceiveTimeoutEnabled();
/**
* @param time
* @param threshold
* @param InputBuffer
*/
private native void NativeEnableReceiveTimeoutThreshold(int time, int threshold, int InputBuffer);
/**
* Set the native serial port parameters If speed is not a predifined speed it is assumed to be the actual speed
* desired.
*/
private native boolean nativeSetSerialPortParams(int speed, int dataBits, int stopBits, int parity)
throws UnsupportedCommOperationException;
@Override
public synchronized void setSerialPortParams(int baudRate, int dataBits, int stopBits, int parity)
throws UnsupportedCommOperationException {
if (nativeSetSerialPortParams(baudRate, dataBits, stopBits, parity)) {
throw new UnsupportedCommOperationException("Invalid Parameter");
}
this.speed = baudRate;
if (stopBits == StopBits.STOPBITS_1_5.value()) {
this.dataBits = DataBits.DATABITS_5.value();
}
else {
this.dataBits = dataBits;
}
this.stopBits = stopBits;
this.parity = parity;
}
@Override
public int getBaudRate() {
return speed;
}
@Override
@Deprecated
public int getDataBits() {
return dataBits;
}
@Override
public DataBits dataBits() {
return Enu.enumFor(this.dataBits, DataBits.class);
}
@Override
@Deprecated
public int getStopBits() {
return stopBits;
}
@Override
public StopBits stopBits() {
return Enu.enumFor(this.stopBits, StopBits.class);
}
@Override
@Deprecated
public int getParity() {
return parity;
}
@Override
public Parity parity() {
return Enu.enumFor(this.parity, Parity.class);
}
@Override
@Deprecated
public void setFlowControlMode(int flowcontrol) {
if (monThreadisInterrupted) {
return;
}
try {
setflowcontrol(flowcontrol);
} catch (IOException e) {
e.printStackTrace();
return;
}
flowmode = flowcontrol;
}
@Override
public void setFlowControlMode(FlowControl flowcontrol) throws UnsupportedCommOperationException {
setFlowControlMode(flowcontrol.value());
}
@Override
@Deprecated
public int getFlowControlMode() {
return flowmode;
}
@Override
public FlowControl flowControlMode() {
return Enu.enumFor(this.flowmode, FlowControl.class);
}
@Override
public void enableReceiveFraming(int f) throws UnsupportedCommOperationException {
throw new UnsupportedCommOperationException("Not supported");
}
@Override
public void disableReceiveFraming() {
}
@Override
public boolean isReceiveFramingEnabled() {
return false;
}
@Override
public int getReceiveFramingByte() {
return 0;
}
@Override
@Deprecated
public void disableReceiveTimeout() {
timeout = -1;
NativeEnableReceiveTimeoutThreshold(timeout, threshold, InputBuffer);
}
@Override
public synchronized int commPortTimeout() {
return this.timeout == -1 ? 0 : this.timeout;
}
@Override
@Deprecated
public void enableReceiveTimeout(int time) {
if (time >= 0) {
timeout = time;
NativeEnableReceiveTimeoutThreshold(time, threshold, InputBuffer);
}
else {
throw new IllegalArgumentException("Unexpected negative timeout value");
}
}
@Override
@Deprecated
public boolean isReceiveTimeoutEnabled() {
return (NativeisReceiveTimeoutEnabled());
}
@Override
@Deprecated
public int getReceiveTimeout() {
return (NativegetReceiveTimeout());
}
@Override
public void enableReceiveThreshold(int threshold) {
if (threshold >= 0) {
this.threshold = threshold;
NativeEnableReceiveTimeoutThreshold(timeout, threshold, InputBuffer);
}
else {
throw new IllegalArgumentException("Unexpected negative threshold value");
}
}
@Override
public void disableReceiveThreshold() {
enableReceiveThreshold(0);
}
@Override
public int getReceiveThreshold() {
return threshold;
}
@Override
public boolean isReceiveThresholdEnabled() {
return (threshold > 0);
}
@Override
public void setInputBufferSize(int size) {
if (size < 0) {
throw new IllegalArgumentException("Unexpected negative buffer size value");
}
else {
InputBuffer = size;
}
}
@Override
public int getInputBufferSize() {
return (InputBuffer);
}
@Override
public void setOutputBufferSize(int size) {
if (size < 0) {
throw new IllegalArgumentException("Unexpected negative buffer size value");
}
else {
OutputBuffer = size;
}
}
@Override
public int getOutputBufferSize() {
return (OutputBuffer);
}
// Line status methods
@Override
public native boolean isDTR();
@Override
public native void setDTR(boolean state);
@Override
public native void setRTS(boolean state);
private native void setDSR(boolean state);
@Override
public native boolean isCTS();
@Override
public native boolean isDSR();
@Override
public native boolean isCD();
@Override
public native boolean isRI();
@Override
public native boolean isRTS();
@Override
public native void sendBreak(int duration);
protected native void writeByte(int b, boolean i) throws IOException;
protected native void writeArray(byte b[], int off, int len, boolean i) throws IOException;
protected native boolean nativeDrain(boolean i) throws IOException;
protected native int nativeavailable() throws IOException;
protected native int readByte() throws IOException;
protected native int readArray(byte b[], int off, int len) throws IOException;
protected native int readTerminatedArray(byte b[], int off, int len, byte t[]) throws IOException;
/** Process SerialPortEvents */
/** DSR flag **/
native void eventLoop();
private native void interruptEventLoop();
/** Close the port */
private native void nativeClose(String name);
public boolean checkMonitorThread() {
if (monThread != null) {
return monThreadisInterrupted;
}
return (true);
}
/*
* Sends an event.
*
* @param event the SerialPortEvent id. E.g. SerialPortEvent.DATA_AVAILABLE
*
* @param state
*
* @return boolean true if the port is closing
*/
boolean sendEvent(int event, boolean state) {
if (fd == 0 || serialPortEventListener == null || monThread == null) {
return true;
}
EventType eventType = Enu.enumFor(event, EventType.class);
switch (eventType) {
case DATA_AVAILABLE:
if (monThread.Data) {
break;
}
return (false);
case OUTPUT_BUFFER_EMPTY:
if (monThread.Output) {
break;
}
return (false);
case CLEAR_TO_SEND:
if (monThread.CTS) {
break;
}
return (false);
case DATA_SET_READY:
if (monThread.DSR) {
break;
}
return (false);
case RING_INDICATOR:
if (monThread.RI) {
break;
}
return (false);
case CARRIER_DETECT:
if (monThread.CD) {
break;
}
return (false);
case OVERRUN_ERROR:
if (monThread.OE) {
break;
}
return (false);
case PARITY_ERROR:
if (monThread.PE) {
break;
}
return (false);
case FRAMING_ERROR:
if (monThread.FE) {
break;
}
return (false);
case BREAK_INTERRUPT:
if (monThread.BI) {
break;
}
return (false);
default:
System.err.println("unknown event: " + event);
return false;
}
SerialPortEvent e = new SerialPortEvent(this, event, !state, state);
if (monThreadisInterrupted) {
return true;
}
if (serialPortEventListener != null) {
serialPortEventListener.serialEvent(e);
}
return fd == 0 || serialPortEventListener == null || monThread == null;
}
@Override
public void addEventListener(SerialPortEventListener listener) throws TooManyListenersException {
/*
* Don't let and notification requests happen until the Eventloop is ready
*/
if (serialPortEventListener != null) {
throw new TooManyListenersException();
}
this.serialPortEventListener = listener;
if (!MonitorThreadAlive) {
MonitorThreadLock = true;
monThread = new MonitorThread();
monThread.start();
waitForTheNativeCodeSilly();
MonitorThreadAlive = true;
}
}
/**
* Remove the serial port event listener
*/
@Override
public void removeEventListener() {
waitForTheNativeCodeSilly();
// if( monThread != null && monThread.isAlive() )
if (monThreadisInterrupted == true) {
monThread = null;
serialPortEventListener = null;
return;
}
else if (monThread != null && monThread.isAlive()) {
monThreadisInterrupted = true;
/*
* Notify all threads in this PID that something is up They will call back to see if its their thread using
* isInterrupted().
*/
interruptEventLoop();
try {
// wait a reasonable moment for the death of the monitor thread
monThread.join(3000);
} catch (InterruptedException ex) {
// somebody called interrupt() on us (ie wants us to abort)
// we dont propagate InterruptedExceptions so lets re-set the flag
Thread.currentThread().interrupt();
return;
}
}
monThread = null;
serialPortEventListener = null;
MonitorThreadLock = false;
MonitorThreadAlive = false;
monThreadisInterrupted = true;
}
/**
* Give the native code a chance to start listening to the hardware or should we say give the native code control of
* the issue.
*
* This is important for applications that flicker the Monitor thread while keeping the port open. In worst case
* test cases this loops once or twice every time.
*/
protected void waitForTheNativeCodeSilly() {
while (MonitorThreadLock) {
try {
Thread.sleep(5);
} catch (Exception e) {
}
}
}
private native void nativeSetEventFlag(int fd, int event, boolean flag);
@Override
public void notifyOnDataAvailable(boolean enable) {
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag(fd, EventType.DATA_AVAILABLE.value(), enable);
monThread.Data = enable;
MonitorThreadLock = false;
}
@Override
public void notifyOnOutputEmpty(boolean enable) {
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag(fd, EventType.OUTPUT_BUFFER_EMPTY.value(), enable);
monThread.Output = enable;
MonitorThreadLock = false;
}
@Override
public void notifyOnCTS(boolean enable) {
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag(fd, EventType.CLEAR_TO_SEND.value(), enable);
monThread.CTS = enable;
MonitorThreadLock = false;
}
@Override
public void notifyOnDSR(boolean enable) {
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag(fd, EventType.DATA_SET_READY.value(), enable);
monThread.DSR = enable;
MonitorThreadLock = false;
}
@Override
public void notifyOnRingIndicator(boolean enable) {
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag(fd, EventType.RING_INDICATOR.value(), enable);
monThread.RI = enable;
MonitorThreadLock = false;
}
@Override
public void notifyOnCarrierDetect(boolean enable) {
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag(fd, EventType.CARRIER_DETECT.value(), enable);
monThread.CD = enable;
MonitorThreadLock = false;
}
@Override
public void notifyOnOverrunError(boolean enable) {
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag(fd, EventType.OVERRUN_ERROR.value(), enable);
monThread.OE = enable;
MonitorThreadLock = false;
}
@Override
public void notifyOnParityError(boolean enable) {
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag(fd, EventType.PARITY_ERROR.value(), enable);
monThread.PE = enable;
MonitorThreadLock = false;
}
@Override
public void notifyOnFramingError(boolean enable) {
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag(fd, EventType.FRAMING_ERROR.value(), enable);
monThread.FE = enable;
MonitorThreadLock = false;
}
@Override
public void notifyOnBreakInterrupt(boolean enable) {
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag(fd, EventType.BREAK_INTERRUPT.value(), enable);
monThread.BI = enable;
MonitorThreadLock = false;
}
boolean closeLock = false;
@Override
public void close() {
try {
synchronized (this) {
while (IOLocked > 0) {
try {
this.wait(500);
} catch (InterruptedException ie) {
// somebody called interrupt() on us
// we obbey and return without without closing the socket
Thread.currentThread().interrupt();
return;
}
}
// we set the closeLock after the above check because we might
// have returned without proceeding
if (closeLock) {
return;
}
closeLock = true;
}
if (fd <= 0) {
return;
}
setDTR(false);
setDSR(false);
if (!monThreadisInterrupted) {
removeEventListener();
}
nativeClose(this.name);
super.close();
fd = 0;
closeLock = false;
} finally {
try {
this.serialIS.close();
} catch (IOException e) {
}
this.closed = true;
}
}
/** Finalize the port */
@Override
protected void finalize() {
if (fd > 0) {
close();
}
}
/** Inner class for SerialOutputStream */
private class SerialOutputStream extends OutputStream {
/**
* @param b
* @throws IOException
*/
@Override
public void write(int b) throws IOException {
if (speed == 0) {
return;
}
if (monThreadisInterrupted) {
return;
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try {
waitForTheNativeCodeSilly();
if (fd == 0) {
throw new IOException();
}
writeByte(b, monThreadisInterrupted);
} finally {
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
/**
* @param b[]
* @throws IOException
*/
@Override
public void write(byte b[]) throws IOException {
if (speed == 0) {
return;
}
if (monThreadisInterrupted) {
return;
}
if (fd == 0) {
throw new IOException();
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try {
waitForTheNativeCodeSilly();
writeArray(b, 0, b.length, monThreadisInterrupted);
} finally {
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
@Override
public void close() throws IOException {
try {
super.close();
} finally {
RXTXPort.this.close();
}
}
/**
* @param b[]
* @param off
* @param len
* @throws IOException
*/
@Override
public void write(byte b[], int off, int len) throws IOException {
if (speed == 0) {
return;
}
if (off + len > b.length) {
throw new IndexOutOfBoundsException("Invalid offset/length passed to read");
}
byte send[] = new byte[len];
System.arraycopy(b, off, send, 0, len);
if (fd == 0) {
throw new IOException();
}
if (monThreadisInterrupted) {
return;
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try {
waitForTheNativeCodeSilly();
writeArray(send, 0, len, monThreadisInterrupted);
} finally {
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
/**
*/
@Override
public void flush() throws IOException {
if (speed == 0) {
return;
}
if (fd == 0) {
throw new IOException();
}
if (monThreadisInterrupted) {
return;
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try {
waitForTheNativeCodeSilly();
/*
* this is probably good on all OS's but for now just sendEvent from java on Sol
*/
if (nativeDrain(monThreadisInterrupted)) {
sendEvent(EventType.OUTPUT_BUFFER_EMPTY.value(), true);
}
} finally {
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
}
/**
* This class is a wrapper for the {@link SerialInputStream}.
*/
private class BetterSerialInputStream extends InputStream {
private static final long SLEEP_TIME = 10L;// TODO: sleep appropriate time
private final SerialInputStream serialInputStream;
public BetterSerialInputStream(SerialInputStream serialInputStream) {
this.serialInputStream = serialInputStream;
}
@Override
public synchronized int read() throws IOException {
long elapsedTime = 0;
do {
if (serialInputStream.available() > 0) {
return serialInputStream.read();
}
try {
Thread.sleep(SLEEP_TIME);
elapsedTime += SLEEP_TIME;
} catch (InterruptedException e) {
// ignore
}
if (closed) {
throw new CommPortException("Connection has been closed..");
}
} while (timeout <= 0 || elapsedTime <= timeout);
throw new CommPortTimeoutException("Timed out, while reading the serial port.");
}
@Override
public int available() throws IOException {
return this.serialInputStream.available();
}
@Override
public void close() throws IOException {
serialInputStream.close();
}
}
private class SerialInputStream extends InputStream {
/**
* @return int the int read
* @throws IOException
* @see java.io.InputStream
*
* timeout threshold Behavior ------------------------------------------------------------------------ 0 0
* blocks until 1 byte is available timeout > 0, threshold = 0, blocks until timeout occurs, returns -1 on
* timeout >0 >0 blocks until timeout, returns - 1 on timeout, magnitude of threshold doesn't play a role.
* 0 >0 Blocks until 1 byte, magnitude of threshold doesn't play a role
*/
@Override
public synchronized int read() throws IOException {
if (fd == 0) {
throw new IOException();
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try {
waitForTheNativeCodeSilly();
int result = readByte();
return result;
} finally {
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
/**
* @param b[]
* @return int number of bytes read
* @throws IOException
*
* timeout threshold Behavior
* ------------------------------------------------------------------------ 0 0 blocks until 1 byte
* is available >0 0 blocks until timeout occurs, returns 0 on timeout >0 >0 blocks until timeout or
* reads threshold bytes, returns 0 on timeout 0 >0 blocks until reads threshold bytes
*/
@Override
public synchronized int read(byte b[]) throws IOException {
int result;
if (monThreadisInterrupted) {
return (0);
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try {
waitForTheNativeCodeSilly();
result = read(b, 0, b.length);
return result;
} finally {
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
/**
* @see InputStream#read(byte[], int, int)
*
* @param b
* the bytes
* @param off
* the offset
* @param len
* the length
* @return the numbernumber of bytes read
* @throws IOException
* timeout threshold Behavior
* ------------------------------------------------------------------------ 0 0 blocks until 1 byte
* is available >0 0 blocks until timeout occurs, returns 0 on timeout >0 >0 blocks until timeout or
* reads threshold bytes, returns 0 on timeout 0 >0 blocks until either threshold # of bytes or len
* bytes, whichever was lower.
*/
@Override
public synchronized int read(byte b[], int off, int len) throws IOException {
int result;
/*
* Some sanity checks
*/
if (fd == 0) {
throw new IOException();
}
if (b == null) {
throw new NullPointerException();
}
if ((off < 0) || (len < 0) || (off + len > b.length)) {
throw new IndexOutOfBoundsException();
}
/*
* Return immediately if len==0
*/
if (len == 0) {
return 0;
}
/*
* See how many bytes we should read
*/
int Minimum = len;
if (threshold == 0) {
/*
* If threshold is disabled, read should return as soon as data are available (up to the amount of
* available bytes in order to avoid blocking) Read may return earlier depending of the receive time
* out.
*/
int a = nativeavailable();
if (a == 0) {
Minimum = 1;
}
else {
Minimum = Math.min(Minimum, a);
}
}
else {
/*
* Threshold is enabled. Read should return when 'threshold' bytes have been received (or when the
* receive timeout expired)
*/
Minimum = Math.min(Minimum, threshold);
}
if (monThreadisInterrupted == true) {
return (0);
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try {
waitForTheNativeCodeSilly();
result = readArray(b, off, Minimum);
return (result);
} finally {
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
/**
* @param b[]
* @param off
* @param len
* @param t[]
* @return int number of bytes read
* @throws IOException
*
* We are trying to catch the terminator in the native code Right now it is assumed that t[] is an
* array of 2 bytes.
*
* if the read encounters the two bytes, it will return and the array will contain the terminator.
* Otherwise read behavior should be the same as read( b[], off, len ). Timeouts have not been well
* tested.
*/
public synchronized int read(byte b[], int off, int len, byte t[]) throws IOException {
int result;
/*
* Some sanity checks
*/
if (fd == 0) {
throw new IOException();
}
if (b == null) {
throw new NullPointerException();
}
if ((off < 0) || (len < 0) || (off + len > b.length)) {
throw new IndexOutOfBoundsException();
}
/*
* Return immediately if len==0
*/
if (len == 0) {
return 0;
}
/*
* See how many bytes we should read
*/
int Minimum = len;
if (threshold == 0) {
/*
* If threshold is disabled, read should return as soon as data are available (up to the amount of
* available bytes in order to avoid blocking) Read may return earlier depending of the receive time
* out.
*/
int a = nativeavailable();
if (a == 0) {
Minimum = 1;
}
else {
Minimum = Math.min(Minimum, a);
}
}
else {
/*
* Threshold is enabled. Read should return when 'threshold' bytes have been received (or when the
* receive timeout expired)
*/
Minimum = Math.min(Minimum, threshold);
}
if (monThreadisInterrupted) {
return 0;
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try {
waitForTheNativeCodeSilly();
result = readTerminatedArray(b, off, Minimum, t);
return (result);
} finally {
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
/**
* @return int bytes available
* @throws IOException
*/
@Override
public synchronized int available() throws IOException {
if (monThreadisInterrupted) {
return (0);
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try {
int r = nativeavailable();
return r;
} finally {
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
}
/**
*/
class MonitorThread extends Thread {
/**
* Note: these have to be separate boolean flags because the SerialPortEvent constants are NOT bit-flags, they
* are just defined as integers from 1 to 10 -DPL
*/
private volatile boolean CTS = false;
private volatile boolean DSR = false;
private volatile boolean RI = false;
private volatile boolean CD = false;
private volatile boolean OE = false;
private volatile boolean PE = false;
private volatile boolean FE = false;
private volatile boolean BI = false;
private volatile boolean Data = false;
private volatile boolean Output = false;
MonitorThread() {
setDaemon(true);
}
/**
* run the thread and call the event loop.
*/
@Override
public void run() {
monThreadisInterrupted = false;
eventLoop();
}
@Override
protected void finalize() throws Throwable {
}
}
/*------------------------ END OF CommAPI -----------------------------*/
private native static void nativeStaticSetSerialPortParams(String f, int b, int d, int s, int p)
throws UnsupportedCommOperationException;
private native static boolean nativeStaticSetDSR(String port, boolean flag)
throws UnsupportedCommOperationException;
private native static boolean nativeStaticSetDTR(String port, boolean flag)
throws UnsupportedCommOperationException;
private native static boolean nativeStaticSetRTS(String port, boolean flag)
throws UnsupportedCommOperationException;
private native static boolean nativeStaticIsDSR(String port) throws UnsupportedCommOperationException;
private native static boolean nativeStaticIsDTR(String port) throws UnsupportedCommOperationException;
private native static boolean nativeStaticIsRTS(String port) throws UnsupportedCommOperationException;
private native static boolean nativeStaticIsCTS(String port) throws UnsupportedCommOperationException;
private native static boolean nativeStaticIsCD(String port) throws UnsupportedCommOperationException;
private native static boolean nativeStaticIsRI(String port) throws UnsupportedCommOperationException;
private native static int nativeStaticGetBaudRate(String port) throws UnsupportedCommOperationException;
private native static int nativeStaticGetDataBits(String port) throws UnsupportedCommOperationException;
private native static int nativeStaticGetParity(String port) throws UnsupportedCommOperationException;
private native static int nativeStaticGetStopBits(String port) throws UnsupportedCommOperationException;
private native byte nativeGetParityErrorChar() throws UnsupportedCommOperationException;
private native boolean nativeSetParityErrorChar(byte b) throws UnsupportedCommOperationException;
private native byte nativeGetEndOfInputChar() throws UnsupportedCommOperationException;
private native boolean nativeSetEndOfInputChar(byte b) throws UnsupportedCommOperationException;
private native boolean nativeSetUartType(String type, boolean test) throws UnsupportedCommOperationException;
native String nativeGetUartType() throws UnsupportedCommOperationException;
private native boolean nativeSetBaudBase(int BaudBase) throws UnsupportedCommOperationException;
private native int nativeGetBaudBase() throws UnsupportedCommOperationException;
private native boolean nativeSetDivisor(int Divisor) throws UnsupportedCommOperationException;
private native int nativeGetDivisor() throws UnsupportedCommOperationException;
private native boolean nativeSetLowLatency() throws UnsupportedCommOperationException;
private native boolean nativeGetLowLatency() throws UnsupportedCommOperationException;
private native boolean nativeSetCallOutHangup(boolean NoHup) throws UnsupportedCommOperationException;
private native boolean nativeGetCallOutHangup() throws UnsupportedCommOperationException;
private native boolean nativeClearCommInput() throws UnsupportedCommOperationException;
/**
* Retrieve the baud rate.
*
* This is only accurate up to 38600 baud currently.
*
*
* @param port
* the name of the port thats been preopened
* @return BaudRate on success
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*
*/
public static int staticGetBaudRate(String port) throws UnsupportedCommOperationException {
return (nativeStaticGetBaudRate(port));
}
/**
* Retrieve the data bits.
*
* @param port
* the name of the port thats been preopened
* @return DataBits on success
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*
*/
public static int staticGetDataBits(String port) throws UnsupportedCommOperationException {
return nativeStaticGetDataBits(port);
}
/**
* Retrieve the parity.
*
* @param port
* the name of the port thats been preopened
* @return Parity on success
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*
*/
public static int staticGetParity(String port) throws UnsupportedCommOperationException {
return nativeStaticGetParity(port);
}
/**
* Retrieve the stop bits.
*
* @param port
* the name of the port thats been preopened
* @return StopBits on success
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*
*/
public static int staticGetStopBits(String port) throws UnsupportedCommOperationException {
return (nativeStaticGetStopBits(port));
}
/**
* Set the SerialPort parameters 1.5 stop bits requires 5 databits
*
* @see gnu.io.UnsupportedCommOperationException
*
* @param filename
* filename
* @param baudrate
* baudrate
* @param databits
* databits
* @param stopbits
* stopbits
* @param parity
* parity
*
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*/
public static void staticSetSerialPortParams(String filename, int baudrate, int databits, int stopbits, int parity)
throws UnsupportedCommOperationException {
nativeStaticSetSerialPortParams(filename, baudrate, databits, stopbits, parity);
}
/**
* Open the port and set DSR. remove lockfile and do not close This is so some software can appear to set the DSR
* before 'opening' the port a second time later on.
*
* @param port
* the port name
* @param flag
* boolean DSR FLAG.
* @return true if the operation was successful
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*/
public static boolean staticSetDSR(String port, boolean flag) throws UnsupportedCommOperationException {
return (nativeStaticSetDSR(port, flag));
}
/**
* Open the port and set DTR. remove lockfile and do not close This is so some software can appear to set the DTR
* before 'opening' the port a second time later on.
*
* @param port
* the port name
* @param flag
* boolean DTR FLAG.
* @return true if the operation was successful
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*
*/
public static boolean staticSetDTR(String port, boolean flag) throws UnsupportedCommOperationException {
return (nativeStaticSetDTR(port, flag));
}
/**
* Open the port and set RTS. remove lockfile and do not close This is so some software can appear to set the RTS
* before 'opening' the port a second time later on.
*
* @param port
* the port name
* @param flag
* boolean RTS FLAG.
* @return true if the operation was successful
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*
*/
public static boolean staticSetRTS(String port, boolean flag) throws UnsupportedCommOperationException {
return nativeStaticSetRTS(port, flag);
}
/**
* find the fd and return RTS without using a Java open() call
*
* @param port
* the port name
* @return true if asserted
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*
*/
public static boolean staticIsRTS(String port) throws UnsupportedCommOperationException {
return (nativeStaticIsRTS(port));
}
/**
* find the fd and return CD without using a Java open() call
*
* @param port
* the port name
* @return true if asserted
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*
*/
public static boolean staticIsCD(String port) throws UnsupportedCommOperationException {
return (nativeStaticIsCD(port));
}
/**
* find the fd and return CTS without using a Java open() call
*
* @param port
* the port name
* @return true if asserted
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*
*/
public static boolean staticIsCTS(String port) throws UnsupportedCommOperationException {
return nativeStaticIsCTS(port);
}
/**
* find the fd and return DSR without using a Java open() call
*
* @param port
* the port name
* @return true if asserted
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*
*/
public static boolean staticIsDSR(String port) throws UnsupportedCommOperationException {
return (nativeStaticIsDSR(port));
}
/**
* Extension to CommAPI This is an extension to CommAPI. It may not be supported on all operating systems.
*
* find the fd and return DTR without using a Java open() call
*
* @param port
* the port name
* @return true if asserted
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*
*/
public static boolean staticIsDTR(String port) throws UnsupportedCommOperationException {
return nativeStaticIsDTR(port);
}
/**
* Find the fd and return RI without using a Java open() call
*
* @param port
* the port name
* @return true if asserted
* @throws UnsupportedCommOperationException
* if this operation is not supported for the OS by the underlying native library.
*/
public static boolean staticIsRI(String port) throws UnsupportedCommOperationException {
return nativeStaticIsRI(port);
}
@Override
public byte getParityErrorChar() throws UnsupportedCommOperationException {
// TODO: Anyone know how to do this in Unix?
return nativeGetParityErrorChar();
}
@Override
public boolean setParityErrorChar(byte b) throws UnsupportedCommOperationException {
// TODO: Anyone know how to do this in Unix?
return nativeSetParityErrorChar(b);
}
@Override
public byte getEndOfInputChar() throws UnsupportedCommOperationException {
// TODO: Anyone know how to do this in Unix?
return nativeGetEndOfInputChar();
}
@Override
public boolean setEndOfInputChar(byte b) throws UnsupportedCommOperationException {
return (nativeSetEndOfInputChar(b));
}
@Override
@Deprecated
public boolean setUARTType(String type, boolean test) throws UnsupportedCommOperationException {
return nativeSetUartType(type, test);
}
@Override
public boolean setUARTType(UARTType type, boolean test) throws UnsupportedCommOperationException {
return nativeSetUartType(type.type(), test);
}
@Override
@Deprecated
public String getUARTType() throws UnsupportedCommOperationException {
return nativeGetUartType();
}
@Override
public UARTType uartType() throws UnsupportedCommOperationException {
return UARTType.typeFor(nativeGetUartType());
}
@Override
public boolean setBaudBase(int BaudBase) throws UnsupportedCommOperationException, IOException {
return nativeSetBaudBase(BaudBase);
}
@Override
public int getBaudBase() throws UnsupportedCommOperationException, IOException {
return nativeGetBaudBase();
}
/**
* Extension to CommAPI. Set Baud Base to 38600 on Linux and W32 before using.
*/
@Override
public boolean setDivisor(int Divisor) throws UnsupportedCommOperationException, IOException {
return nativeSetDivisor(Divisor);
}
/**
* Extension to CommAPI
*/
@Override
public int getDivisor() throws UnsupportedCommOperationException, IOException {
return nativeGetDivisor();
}
@Override
public boolean setLowLatency() throws UnsupportedCommOperationException {
return nativeSetLowLatency();
}
@Override
public boolean getLowLatency() throws UnsupportedCommOperationException {
return nativeGetLowLatency();
}
// return true on success
@Override
public boolean setCallOutHangup(boolean NoHup) throws UnsupportedCommOperationException {
return nativeSetCallOutHangup(NoHup);
}
// return true on success
@Override
public boolean getCallOutHangup() throws UnsupportedCommOperationException {
return nativeGetCallOutHangup();
}
// return true on success
public boolean clearCommInput() throws UnsupportedCommOperationException {
return nativeClearCommInput();
}
@Override
public synchronized void setSerialPortParams(int baudRate, DataBits dataBits, StopBits stopBits, Parity parity)
throws UnsupportedCommOperationException {
setSerialPortParams(baudRate, dataBits.value(), stopBits.value(), parity.value());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy