SerialPortWriter.java
/*
* Copyright © 2016 Greg Chabala
*
* This file is part of brick-control-lab.
*
* brick-control-lab 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.
*
* brick-control-lab 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 brick-control-lab. If not, see http://www.gnu.org/licenses/.
*/
package org.chabala.brick.controllab;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.IOException;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
/**
* Owner of all writing activity for a serial port. Manages consistent logging
* and ownership of the keep alive monitor for the port.
*/
class SerialPortWriter implements Closeable {
/**
* When sending commands longer than this threshold, log them as strings
* instead of hex values. In practice, this is only needed for the initial
* handshake, which makes more sense to show as a string.
*/
private static final int STRING_LOGGING_THRESHOLD = 10;
private final Logger log = LoggerFactory.getLogger(getClass());
private final SerialPort serialPort;
private KeepAliveMonitor keepAliveMonitor;
SerialPortWriter(SerialPort serialPort) {
this.serialPort = serialPort;
}
void startKeepAlives() {
keepAliveMonitor = new KeepAliveMonitor(this);
}
String getPortName() {
return serialPort.getPortName();
}
void sendCommand(byte[] bytes, Logger log) throws IOException {
if (serialPort == null) {
throw new IOException("Not connected to control lab");
}
if (keepAliveMonitor != null) {
keepAliveMonitor.reset();
}
if (serialPort.isOpen()) {
if (log.isInfoEnabled()) {
if (bytes.length > STRING_LOGGING_THRESHOLD) {
String portName = serialPort.getPortName();
log.info("{} TX -> {}", portName, new String(bytes, ISO_8859_1));
} else if (log.isDebugEnabled()) {
String portName = serialPort.getPortName();
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("0x%02X ", b));
}
log.debug("{} TX -> {}", portName, sb);
}
}
serialPort.write(bytes);
}
}
void sendCommand(byte[] bytes) throws IOException {
sendCommand(bytes, log);
}
void sendCommand(byte b) throws IOException {
sendCommand(new byte[]{b});
}
void sendCommand(byte b, Logger log) throws IOException {
sendCommand(new byte[]{b}, log);
}
void sendCommand(byte b1, byte b2) throws IOException {
sendCommand(new byte[]{b1, b2});
}
@Override
public void close() {
if (keepAliveMonitor != null) {
keepAliveMonitor.close();
keepAliveMonitor = null;
}
}
}