All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bidib.jbidibc.netbidib.server.adapter.PJCSerialHostAdapter Maven / Gradle / Ivy

There is a newer version: 2.0.28
Show 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.purejavacomm.PureJavaCommSerialConnector;
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 PureJavaCommSerialConnector for communication.
 */
public class PJCSerialHostAdapter extends DefaultHostAdapter {
    private static final Logger LOGGER = LoggerFactory.getLogger(PJCSerialHostAdapter.class);

    private static final Logger LOGGER_CONNECTOR = LoggerFactory.getLogger(PureJavaCommSerialConnector.class);

    private BaseBidib rawSerialBidib;

    private PureJavaCommSerialConnector connector;

    private SerialRawMessageReceiver serialMessageReceiver;

    private String configuredPort;

    private String connectedPort;

    private ConnectionListener localConnectionListener;

    public PJCSerialHostAdapter(Function messageContentSupplier) {
        super(messageContentSupplier);
    }

    @Override
    public void initialize(final Context context) {
        super.initialize(context);

        LOGGER.info("Create the PureJavaCommSerialConnector instance for communication with the backend.");

        connector = new PureJavaCommSerialConnector() {
            @Override
            public void open(String portName, ConnectionListener connectionListener, 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.");
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy