org.energy_home.jemma.javagal.layers.data.implementations.SerialCommRxTx.java Source code

Java tutorial

Introduction

Here is the source code for org.energy_home.jemma.javagal.layers.data.implementations.SerialCommRxTx.java

Source

/**
 * This file is part of JEMMA - http://jemma.energy-home.org
 * (C) Copyright 2013 Telecom Italia (http://www.telecomitalia.it)
 *
 * JEMMA is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (LGPL) version 3
 * or later as published by the Free Software Foundation, which accompanies
 * this distribution and is available at http://www.gnu.org/licenses/lgpl.html
 *
 * JEMMA 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 (LGPL) for more details.
 *
 */
package org.energy_home.jemma.javagal.layers.data.implementations;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;

import java.io.IOException;
import java.io.InputStream;
import java.util.TooManyListenersException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.energy_home.jemma.javagal.layers.data.interfaces.IConnector;
import org.energy_home.jemma.javagal.layers.data.interfaces.IDataLayer;
import org.energy_home.jemma.javagal.layers.object.ByteArrayObject;
import org.energy_home.jemma.zgd.GatewayConstants;
import org.energy_home.jemma.zgd.jaxb.Status;

/**
 * RxTx implementation of the {@link IConnector}.
 * 
 * @author 
 *         "Ing. Marco Nieddu <marco.nieddu@consoft.it> or <marco.niedducv@gmail.com> from Consoft Sistemi S.P.A.<http://www.consoft.it>, financed by EIT ICT Labs activity SecSES - Secure Energy Systems (activity id 13030)"
 * 
 */
public class SerialCommRxTx implements IConnector {
    private boolean connected = false;
    private SerialPort serialPort;
    private final static Log logger = LogFactory.getLog(SerialCommRxTx.class);
    CommPortIdentifier portIdentifier;
    InputStream in = null;
    private SerialReader serialReader = null;

    private IDataLayer DataLayer = null;
    private String commport = "";
    private int boudrate = 0;

    /**
     * Creates a new instance.
     * 
     * @param _portName
     *            the port name.
     * @param _boudRate
     *            the baud rate.
     * @param _DataLayer
     *            an actual implementation of the {@code IDataLayer} to use in
     *            this connection.
     * @throws Exception
     *             if an error occurs.
     */
    public SerialCommRxTx(String _portName, int _boudRate, IDataLayer _DataLayer) throws Exception {
        DataLayer = _DataLayer;
        commport = _portName;
        boudrate = _boudRate;
    }

    /**
     * Gets the actual DataLayer implementation used by this connection.
     */
    public IDataLayer getDataLayer() {
        return DataLayer;
    }

    /**
     * @inheritDoc
     */
    private boolean connect(String portName, int speed) throws Exception {

        try {
            System.setProperty("gnu.io.rxtx.SerialPorts", portName);
            portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
            if (portIdentifier.isCurrentlyOwned()) {
                logger.error("Error: Port is currently in use:" + portName);
                disconnect();
                return false;
            } else {

                serialPort = (SerialPort) portIdentifier.open(this.getClass().getName(), 2000);
                if (serialPort instanceof SerialPort) {
                    /*Freescale code*/
                    serialPort.setSerialPortParams(speed, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
                            SerialPort.PARITY_NONE);
                    serialPort.setFlowControlMode(
                            SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT);
                    serialPort.setRTS(true);
                    serialPort.setDTR(true);
                    serialPort.enableReceiveTimeout(1000);
                    in = serialPort.getInputStream();
                    serialReader = new SerialReader(in, this);
                    try {
                        serialPort.addEventListener(serialReader);
                    } catch (TooManyListenersException e) {
                        disconnect();
                        throw new Exception("Error Too Many Listeners Exception on  serial port:" + e.getMessage());
                    }
                    serialPort.notifyOnDataAvailable(true);
                    if (DataLayer.getPropertiesManager().getDebugEnabled())
                        logger.info("Connection on " + portName + " established");

                    /*
                    serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
                    serialPort.setSerialPortParams(speed, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
                    in = serialPort.getInputStream();
                    serialReader = new SerialReader(in, this);
                    try {
                       serialPort.addEventListener(serialReader);
                    } catch (TooManyListenersException e) {
                       disconnect();
                       throw new Exception("Error Too Many Listeners Exception on  serial port:" + e.getMessage());
                    }
                    serialPort.notifyOnDataAvailable(true);
                    if (DataLayer.getPropertiesManager().getDebugEnabled())
                       logger.info("Connection on " + portName + " established");
                    */
                    return true;
                } else {
                    if (DataLayer.getPropertiesManager().getDebugEnabled())
                        logger.error("Error on serial port connection:" + portName);
                    disconnect();
                    return false;
                }
            }

        } catch (NoSuchPortException e) {
            if (DataLayer.getPropertiesManager().getDebugEnabled())
                logger.error("the connection could not be made: NoSuchPortException " + portName);
            disconnect();
            return false;
        } catch (PortInUseException e) {
            if (DataLayer.getPropertiesManager().getDebugEnabled())
                logger.error("the connection could not be made: PortInUseException");
            disconnect();
            return false;
        } catch (UnsupportedCommOperationException e) {
            if (DataLayer.getPropertiesManager().getDebugEnabled())
                logger.error("the connection could not be made: UnsupportedCommOperationException");
            disconnect();
            return false;
        }

    }

    /**
     * @inheritDoc
     */
    public void write(ByteArrayObject buff) throws Exception {

        if (isConnected()) {
            synchronized (serialPort.getOutputStream()) {

                if (serialPort.getOutputStream() != null) {
                    serialPort.getOutputStream().write(buff.getByteArray(), 0, buff.getByteCount(true));
                    serialPort.getOutputStream().flush();
                } else
                    throw new Exception("Error on serial write - out == null");

            }
        }

    }

    /**
     * @inheritDoc
     */
    @Override
    public boolean isConnected() {
        return connected;
    }

    /**
     * @inheritDoc
     */
    @Override
    public void disconnect() throws IOException {

        if (serialPort != null) {
            if (in != null) {
                in.close();
                in = null;
            }
            if (serialPort.getOutputStream() != null)
                serialPort.getOutputStream().close();

            serialPort.removeEventListener();
            serialPort.close();
            serialPort = null;
            serialReader = null;
            portIdentifier = null;
        }
        synchronized (this) {
            connected = false;
        }
        if (DataLayer.getPropertiesManager().getDebugEnabled())
            logger.info("Disconnected");
    }

    class SerialReader implements SerialPortEventListener {
        InputStream in;
        private byte[] buffer = new byte[1024];
        IConnector _caller = null;

        public SerialReader(InputStream in, IConnector _parent) {
            this.in = in;
            _caller = _parent;
        }

        @Override
        public void serialEvent(SerialPortEvent event) {
            try {
                switch (event.getEventType()) {
                case SerialPortEvent.BI:
                case SerialPortEvent.OE:
                case SerialPortEvent.FE:
                case SerialPortEvent.PE:
                case SerialPortEvent.CD:
                case SerialPortEvent.CTS:
                case SerialPortEvent.DSR:
                case SerialPortEvent.RI:
                case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
                    break;
                case SerialPortEvent.DATA_AVAILABLE: {
                    try {
                        int pos = 0;
                        int data = 0;
                        while (in.available() > 0) {
                            data = in.read();
                            buffer[pos++] = (byte) data;
                        }
                        ByteArrayObject frame = new ByteArrayObject(buffer, pos);
                        _caller.getDataLayer().notifyFrame(frame);
                    } catch (Exception e) {
                        if (DataLayer.getPropertiesManager().getDebugEnabled())
                            logger.error("Error on data received:" + e.getMessage());
                    }
                }
                }
            } catch (Exception e) {
                if (DataLayer.getPropertiesManager().getDebugEnabled())
                    logger.error("Error on read from serial data:" + e.getMessage());

            }

        }
    }

    /**
     * @inheritDoc
     */
    public void initialize() throws Exception {
        synchronized (this) {
            connected = true;
        }
        if (DataLayer.getPropertiesManager().getDebugEnabled())
            logger.info("Starting inizialize procedure for: PortName=" + commport + "Speed=" + boudrate);
        if (!connect(commport, boudrate)) {
            throw new Exception("Unable to connect to serial port!");
        }
        DataLayer.cpuReset();
        if (DataLayer.getPropertiesManager().getDebugEnabled())
            logger.info("Waiting 2,5 seconds after command CPUReset...");
        Thread.sleep(2500);
        synchronized (this) {
            connected = true;
        }
        Status _status = DataLayer.SetModeSelectSync(DataLayer.getPropertiesManager().getCommandTimeoutMS());
        if (_status.getCode() != GatewayConstants.SUCCESS)
            throw new Exception("Errorn on SetMode:" + _status.getMessage());
        else {
            if (DataLayer.getPropertiesManager().getDebugEnabled())
                logger.info("Connected: PortName=" + commport + "Speed=" + boudrate);
            synchronized (this) {
                connected = true;
            }
        }
    }

}