org.bidib.jbidibc.netbidib.server.adapter.RxtxSerialHostAdapter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jbidibc-netbidib-server Show documentation
Show all versions of jbidibc-netbidib-server Show documentation
jBiDiB jbidibc NetBiDiB Server POM
The newest version!
package org.bidib.jbidibc.netbidib.server.adapter;
import java.util.function.Function;
import org.bidib.jbidibc.messages.BidibMessagePublisher;
import org.bidib.jbidibc.messages.ConnectionListener;
import org.bidib.jbidibc.messages.MessageReceiver;
import org.bidib.jbidibc.messages.SequenceNumberProvider;
import org.bidib.jbidibc.messages.base.BaseBidib;
import org.bidib.jbidibc.messages.base.ConnectionStatusListener;
import org.bidib.jbidibc.messages.exception.InvalidConfigurationException;
import org.bidib.jbidibc.messages.exception.PortNotFoundException;
import org.bidib.jbidibc.messages.exception.PortNotOpenedException;
import org.bidib.jbidibc.messages.helpers.Context;
import org.bidib.jbidibc.messages.message.BidibMessageInterface;
import org.bidib.jbidibc.messages.utils.ByteUtils;
import org.bidib.jbidibc.messages.utils.StringUtils;
import org.bidib.jbidibc.netbidib.NetBidibContextKeys;
import org.bidib.jbidibc.rxtx.RxtxSerialConnector;
import org.bidib.jbidibc.serial.raw.MessagePublisher;
import org.bidib.jbidibc.serial.raw.SerialRawMessageReceiver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class uses RxtxSerialConnector for communication.
*/
public class RxtxSerialHostAdapter extends DefaultHostAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(RxtxSerialHostAdapter.class);
private static final Logger LOGGER_CONNECTOR = LoggerFactory.getLogger(RxtxSerialConnector.class);
private BaseBidib rawSerialBidib;
private RxtxSerialConnector connector;
private SerialRawMessageReceiver serialMessageReceiver;
private String configuredPort;
private String connectedPort;
private ConnectionListener localConnectionListener;
public RxtxSerialHostAdapter(Function messageContentSupplier) {
super(messageContentSupplier);
}
@Override
public void initialize(final Context context) {
super.initialize(context);
LOGGER.info("Create the ScmSerialConnector instance for communication with the backend.");
connector = new RxtxSerialConnector() {
@Override
public void open(String portName, final ConnectionListener connectionListener, final Context context)
throws PortNotFoundException, PortNotOpenedException {
internalOpen(portName, context);
if (connectionListener != null) {
connectionListener.opened(portName);
}
}
};
org.bidib.jbidibc.messages.logger.Logger connectorLogger = new org.bidib.jbidibc.messages.logger.Logger() {
@Override
public void debug(String format, Object... arguments) {
LOGGER_CONNECTOR.debug(format, arguments);
}
@Override
public void info(String format, Object... arguments) {
LOGGER_CONNECTOR.info(format, arguments);
}
@Override
public void warn(String format, Object... arguments) {
LOGGER_CONNECTOR.warn(format, arguments);
}
@Override
public void error(String format, Object... arguments) {
LOGGER_CONNECTOR.error(format, arguments);
}
};
this.connector.setLogger(connectorLogger);
serialMessageReceiver = createMessageReceiver(context);
connector.setMessageReceiver(serialMessageReceiver);
connector.setConnectionStatusListener(new ConnectionStatusListener() {
@Override
public void notifyOpened() {
}
@Override
public void notifyClosed() {
LOGGER
.info("The connection status listener notified the close connection. Current connected port: {}",
connectedPort);
fireClosed(connectedPort);
}
});
connector.initialize();
rawSerialBidib = connector;
}
private SerialRawMessageReceiver createMessageReceiver(final Context context) {
LOGGER.info("Create the serial message receiver.");
final SerialRawMessageReceiver serialMessageReceiver =
new SerialRawMessageReceiver(true, new MessagePublisher() {
@Override
public void publishMessage(final BidibMessageInterface bidibMessage) {
// publish the raw message to the host
getToGuestPublisher().publishBidibMessage(null, messageContentSupplier.apply(bidibMessage));
}
});
serialMessageReceiver.init(context);
return serialMessageReceiver;
}
/**
* @return the rawSerialBidib
*/
public BaseBidib getRawSerialBidib() {
return rawSerialBidib;
}
/**
* @param rawSerialBidib
* the rawSerialBidib to set
*/
public void setRawSerialBidib(BaseBidib rawSerialBidib) {
this.rawSerialBidib = rawSerialBidib;
}
/**
* Returns the configured port that was provided during connect backend.
*
* @return the configured port
*/
public String getConfiguredPort() {
return configuredPort;
}
@Override
public void signalConnectionOpened(final Context context) {
if (rawSerialBidib == null) {
LOGGER.error("No backend configured. Abort connect to backend.");
throw new InvalidConfigurationException("No backend configured. Abort connect to backend.");
}
String portName = context.get(NetBidibContextKeys.KEY_PORT, String.class, null);
if (StringUtils.isBlank(portName)) {
LOGGER.error("No backend portName configured. Abort connect to backend.");
throw new InvalidConfigurationException("No backend portName configured. Abort connect to backend.");
}
final ConnectionListener connectionListener =
context.get(NetBidibContextKeys.KEY_CONNECTION_LISTENER, ConnectionListener.class, null);
LOGGER.info("Connect the backend, port: {}, connectionListener: {}", portName, connectionListener);
this.localConnectionListener = new ConnectionListener() {
@Override
public void status(String messageKey, final Context context) {
if (connectionListener != null) {
connectionListener.status(messageKey, context);
}
}
@Override
public void opened(String port) {
LOGGER.info("Port was opened, notify the connection listener.");
if (connectionListener != null) {
connectionListener.opened(port);
}
}
@Override
public void closed(String port) {
if (connectionListener != null) {
connectionListener.closed(port);
}
LOGGER.info("Port was closed, stop receiver and queues.");
connector.stopReceiverAndQueues(null);
}
@Override
public void stall(boolean stall) {
// TODO Auto-generated method stub
}
};
configuredPort = portName;
try {
rawSerialBidib.open(portName, this.localConnectionListener, context);
connectedPort = portName;
setToBackendPublisher(new BidibMessagePublisher() {
@Override
public void publishBidibMessage(final SequenceNumberProvider node, final T message) {
byte[] content = null;
if (message instanceof BidibMessageInterface) {
content = (byte[]) messageContentSupplier.apply((BidibMessageInterface) message);
}
else if (message instanceof byte[]) {
content = (byte[]) message;
}
if (content != null) {
LOGGER
.info("Publish the bidib message content from stream to the backend: {}",
ByteUtils.bytesToHex(content));
connector.send(content);
}
else {
LOGGER.warn("No content to send available.");
}
}
});
serialMessageReceiver.enable();
}
catch (PortNotFoundException ex) {
LOGGER.warn("Open port failed.", ex);
fireClosed(portName);
InvalidConfigurationException icex = new InvalidConfigurationException("Open port failed.", ex);
throw icex;
}
catch (PortNotOpenedException ex) {
LOGGER.warn("Open port failed.", ex);
fireClosed(portName);
InvalidConfigurationException icex = new InvalidConfigurationException("Open port failed.", ex);
icex.setReason(ex.getReason());
throw icex;
}
}
@Override
public void signalConnectionClosed(final Context context) {
if (rawSerialBidib == null) {
LOGGER.error("No backend configured. Abort disconnect from backend.");
throw new InvalidConfigurationException("No backend configured. Abort disconnect from backend.");
}
LOGGER.info("Disconnect from the backend.");
serialMessageReceiver.disable();
try {
rawSerialBidib.close();
}
catch (Exception ex) {
LOGGER.warn("Close port failed.", ex);
}
fireClosed(connectedPort);
connectedPort = null;
configuredPort = null;
LOGGER.info("Disconnect port has passed.");
}
private void fireClosed(String portName) {
LOGGER.info("The port was closed: {}", portName);
if (this.localConnectionListener != null) {
LOGGER.info("Notify the local connection listener that the port is closed.");
try {
this.localConnectionListener.closed(portName);
}
catch (Exception ex) {
LOGGER.warn("Notify the local connection listener that the port is closed has failed.", ex);
}
this.localConnectionListener = null;
}
else {
LOGGER.info("No local connection listener assigned.");
}
}
}