org.bidib.jbidibc.serial.SerialMessageReceiver Maven / Gradle / Ivy
package org.bidib.jbidibc.serial;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import org.bidib.jbidibc.core.BidibLibrary;
import org.bidib.jbidibc.core.MessageReceiver;
import org.bidib.jbidibc.core.exception.InvalidConfigurationException;
import org.bidib.jbidibc.core.exception.ProtocolException;
import org.bidib.jbidibc.core.node.NodeFactory;
import org.bidib.jbidibc.core.utils.ByteUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SerialMessageReceiver extends MessageReceiver {
private static final Logger LOGGER = LoggerFactory.getLogger(SerialMessageReceiver.class);
private byte[] inputBuffer = new byte[1024];
boolean escapeHot = false;
private final Object accessLock = new Object();
private ByteArrayOutputStream output = new ByteArrayOutputStream(1024);
public SerialMessageReceiver(NodeFactory nodeFactory) {
super(nodeFactory);
}
public void enable() {
LOGGER.info("enable is called.");
synchronized (accessLock) {
escapeHot = false;
}
super.enable();
}
public void disable() {
LOGGER.info("Disable is called.");
super.disable();
synchronized (accessLock) {
escapeHot = false;
}
}
@Override
public String getErrorInformation() {
if (output != null && output.size() > 0) {
byte[] remaining = output.toByteArray();
return new String(remaining);
}
return null;
}
public void purgeOutputStream() {
synchronized (accessLock) {
LOGGER.info("Purge the output stream. Current escapeHot: {}", escapeHot);
escapeHot = false;
if (output != null && output.size() > 0) {
try {
byte[] remaining = output.toByteArray();
String remainingValue = new String(remaining, Charset.forName("UTF-8"));
LOGGER.info("Cleared remaining data from message output buffer: {}, text: {}",
ByteUtils.bytesToHex(remaining), remainingValue);
if (remainingValue.indexOf("I=") > -1) {
// This is the detection of the debug interface active
InvalidConfigurationException ice =
new InvalidConfigurationException("An active debug interface configuration was detected.");
ice.setReason("debug-interface-active");
throw ice;
}
}
catch (UnsupportedCharsetException ex) {
LOGGER.warn("Clear remaining data from message output buffer failed.", ex);
}
finally {
output.reset();
}
}
}
}
/**
* Receive messages from the configured port
*/
public void receive(final InputStream input) {
LOGGER.debug("Start receiving messages from port.");
if (!running.get()) {
LOGGER.info("The receiver is not running. Skip processing of messages.");
return;
}
synchronized (accessLock) {
LOGGER.debug("Start processing input stream.");
// InputStream input = null;
try {
if (input != null) {
// input = port.getInputStream();
parseInput(input);
}
else {
LOGGER.warn("Inside receive, port is not available");
}
}
catch (Exception e) {
LOGGER.warn("Exception detected in message receiver!", e);
// reset the escapeHot flag
if (escapeHot) {
LOGGER.warn("Reset the escapeHot to false.");
escapeHot = false;
}
throw new RuntimeException(e);
}
}
}
protected void parseInput(final InputStream input) throws IOException, ProtocolException {
if (input != null) {
int data = 0;
StringBuilder logRecord = new StringBuilder();
// read the values from in the port
int len = 0;
while (running.get() && (len = input.read(inputBuffer, 0, inputBuffer.length)) > 0) {
LOGGER.debug("Number of bytes read: {}", len);
MSG_RAW_LOGGER.info("<<<< len: {}", len);
for (int index = 0; index < len; index++) {
data = (inputBuffer[index] & 0xFF);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("received data: {}", ByteUtils.byteToHex(data));
}
// append data to log record
logRecord.append(ByteUtils.byteToHex(data)).append(" ");
// check if the current is the end of a packet
if (data == BidibLibrary.BIDIB_PKT_MAGIC && output.size() > 0) {
LOGGER.debug("Received raw message: {}", logRecord);
if (MSG_RAW_LOGGER.isInfoEnabled()) {
MSG_RAW_LOGGER.info("<< [{}] - {}", logRecord.length() / 3, logRecord);
}
logRecord.setLength(0);
// if a CRC error is detected in splitMessages the reading loop will terminate ...
try {
processMessages(output);
}
catch (ProtocolException ex) {
LOGGER.warn("Process messages failed.", ex);
// reset the escape hot flag
escapeHot = false;
}
// after process messages there could be more data in the stream that will be continued with
// the next packet
}
else {
if (data == BidibLibrary.BIDIB_PKT_ESCAPE) {
escapeHot = true;
}
else if (data != BidibLibrary.BIDIB_PKT_MAGIC) {
if (escapeHot) {
data ^= 0x20;
escapeHot = false;
}
// append data to output array
output.write(ByteUtils.getLowByte(data));
}
}
// if (!running.get()) {
// LOGGER.warn("Abort processing input because the receiver was stopped.");
// break;
// }
}
}
LOGGER.debug("Leaving receive loop, RUNNING: {}", running);
if (output != null && output.size() > 0) {
byte[] remaining = output.toByteArray();
String remainingString = ByteUtils.bytesToHex(remaining);
LOGGER.debug("Data remaining in output: {}", remainingString);
}
if (logRecord != null && logRecord.length() > 0) {
LOGGER.debug("Data remaining in logRecord: {}", logRecord);
}
}
else {
LOGGER.error("No input available.");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy