/** * * Copyright (c) 2009-2016 Freedomotic team http://freedomotic.com * * This file is part of Freedomotic * * This Program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2, or (at your option) any later version. * * This Program 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 General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * Freedomotic; see the file COPYING. If not, see * <http://www.gnu.org/licenses/>. */ package com.freedomotic.helpers; import java.util.Arrays; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import jssc.*; /** * Provides connection to serial ports and handles serial port reading and * writing. One or more SerialPortListener can be registered to receive a copy * of the data read from serial * * To use this class make your client class to implement the SerialPortListener * interface and pass a 'this' reference in the constructor of * SerialConnectionProvider. * * @author Enrico Nicoletti */ public class SerialHelper { private static final Logger LOG = LoggerFactory.getLogger(SerialHelper.class.getName()); private SerialPort serialPort; private String portName; private String readTerminator = ""; private int readChunkSize = -1; private StringBuilder readBuffer = new StringBuilder(); /** * Accepts default parameters and change only the port name. The connect() * method should be called to initialize the serial port connection. * * @param portName serial port name * @param baudRate serial port baud rate * @param dataBits serial port data bits * @param stopBits serial port stop bits * @param parity serial port parity bit * @param consumer serial port listener * @throws jssc.SerialPortException */ public SerialHelper(final String portName, int baudRate, int dataBits, int stopBits, int parity, final SerialPortListener consumer) throws SerialPortException { this.portName = portName; serialPort = new SerialPort(this.portName); serialPort.addEventListener(new SerialPortEventListener() { @Override public void serialEvent(SerialPortEvent event) { if (event.isRXCHAR()) { if (event.getEventValue() > 0) { try { readBuffer.append(new String(serialPort.readBytes())); } catch (SerialPortException ex) { LOG.warn(ex.getMessage()); } } LOG.info("Received message \"{}\" from serial port \"{}\"", new Object[]{readBuffer.toString(), portName}); sendReadData(consumer); } } }); serialPort.setParams(baudRate, dataBits, stopBits, parity); } /** * Sends a string message to the device. * * @param message the message to send * @return true if executed succesfully, false otherwise * @throws jssc.SerialPortException */ public boolean write(String message) throws SerialPortException { LOG.info("Writing \"{}\" to serial port \"{}\"", new Object[]{message, portName}); return serialPort.writeString(message); } /** * Sends a bytes message to the device * * @param bytes the message to send * @return * @throws jssc.SerialPortException */ public boolean write(byte[] bytes) throws SerialPortException { LOG.info("Writing bytes \"{}\" to serial port \"{}\"", new Object[]{Arrays.toString(bytes), portName}); return serialPort.writeBytes(bytes); } /** * Returns port names. * * @return a string vector of port names */ public String[] getPortNames() { String[] serialPortList = SerialPortList.getPortNames(); if (serialPortList.length == 0) { LOG.error("No serial ports found"); } return serialPortList; } /** * Returns port name * * @return portName the port name */ public String getPortName() { return serialPort.getPortName(); } /** * Returns port status * * @return isOpened true if the port is opened, false otherwise */ public boolean isOpened() { return serialPort.isOpened(); } /** * Disconnects the port * * @return */ public boolean disconnect() { try { return serialPort.closePort(); } catch (SerialPortException ex) { LOG.warn("Error while closing serial port \"" + serialPort.getPortName() + "\"", ex); return false; } } /** * Sets port DTR * * @param enabled */ public void setDTR(boolean enabled) { try { serialPort.setDTR(enabled); } catch (SerialPortException ex) { LOG.error(ex.getMessage()); } } /** * Sets port RTS * * @param enabled */ public void setRTS(boolean enabled) { try { serialPort.setRTS(enabled); } catch (SerialPortException ex) { LOG.error(ex.getMessage()); } } /** * Sets chunck terminator * * @param readTerminator the terminator symbol used for data splitting */ public void setChunkTerminator(String readTerminator) { this.readTerminator = readTerminator; //disable chunk size splitting this.readChunkSize = -1; } /** * Sets chunck size * * @param chunkSize the chunck size used for data splitting */ public void setChunkSize(int chunkSize) { this.readChunkSize = chunkSize; // disable chunk terminator splitting this.readTerminator = ""; } /** * Sends read data to the listener * * @param consumer serial port listener */ public void sendReadData(SerialPortListener consumer) { String bufferContent = readBuffer.toString(); // if a terminator is configured if (!readTerminator.isEmpty()) { // consume chunks until terminator string is reached while (bufferContent.contains(readTerminator)) { int endOfTerminator = bufferContent.indexOf(readTerminator) + readTerminator.length(); String chunk = bufferContent.substring(0, endOfTerminator); //remove this chunk of data from bufferContent bufferContent = bufferContent.substring(endOfTerminator); consumer.onDataAvailable(chunk); } } else { if (readChunkSize > 0) { // consume chunks of the given size while (readChunkSize > 0 && bufferContent.length() >= readChunkSize) { String chunk = bufferContent.substring(0, readChunkSize); //remove this chunk of data from bufferContent bufferContent = bufferContent.substring(readChunkSize); consumer.onDataAvailable(chunk); } } else { // no splitting, send it just as readed consumer.onDataAvailable(bufferContent); //clear from sent text bufferContent = ""; } } // Clear the buffer for sent text readBuffer.setLength(0); readBuffer.append(bufferContent); } }