Ilker M. Karakas
Ilker M. Karakas

Reputation: 53

Read and Write Timeouts in JSSC

In SerialPort.java, I would like to know the following on writeBytes and readBytes methods:

Upvotes: 2

Views: 3327

Answers (1)

k_o_
k_o_

Reputation: 6308

For reading (I'm using version 2.8.0) there are also methods like readBytes(int byteCount, int timeout) where you can specify a timeout. For reading the better approach might be to register a SerialPortEventListener. In fact I have never tried to uses readBytes directly outside of it.

The boolean return code must be true for the writing methods. The reason for this is the return code coming from the C++ JNI implementation behind. No exception is thrown in the JNI part, better would be also an exception here.

If you look into the Java code of e.g. writeBytes(byte[] buffer) only the first line is throwing a SerialPortException, the actual transmission is handled with the boolean return code:

this.checkPortOpened("writeBytes()");
return this.serialInterface.writeBytes(this.portHandle, buffer);

The write part can block, e.g. if the serial port is not responding. I have used a thread to prevent this, something like this:

private static class BackgroundWriter implements Callable<Boolean> {

    private SerialPort serialPort;

    private String atCommand;

    public BackgroundWriter(SerialPort serialPort, String atCommand) {
        this.serialPort = serialPort;
        this.atCommand = atCommand;
    }

    @Override
    public Boolean call() throws Exception {
        // add carriage return
        boolean success = serialPort.writeString(atCommand+"\r");
        return success;
    }
}

and later call it with a timeout:

ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Boolean> writeResult = executorService.submit(new BackgroundWriter(serialPort, atCommand));
boolean success;
try {
    success = writeResult.get(writeTimeout, TimeUnit.MILLISECONDS);
} catch (Exception e) {
    if (serialPort != null && serialPort.isOpened()) {
        try {
            serialPort.closePort();
        } catch (SerialPortException e2) {
            LOGGER.warn("Could not close serial port after timeout.", e2);
        }
    }
    throw new IOException("Could not write to serial port due to timeout.", e);
}
if (!success) {
    throw new IOException("Could not write to serial port [" + serialPort.getPortName() + "]");
}

Upvotes: 3

Related Questions