sl@0: /* sl@0: * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: import gnu.io.CommPort; sl@0: import gnu.io.CommPortIdentifier; sl@0: import gnu.io.SerialPort; sl@0: import gnu.io.SerialPortEvent; sl@0: import gnu.io.SerialPortEventListener; sl@0: sl@0: import java.util.logging.Logger; sl@0: sl@0: import org.apache.commons.cli.Options; sl@0: import org.apache.commons.cli.Option; sl@0: import org.apache.commons.cli.OptionBuilder; sl@0: import org.apache.commons.cli.CommandLineParser; sl@0: import org.apache.commons.cli.PosixParser; sl@0: import org.apache.commons.cli.CommandLine; sl@0: import org.apache.commons.cli.HelpFormatter; sl@0: sl@0: public class UartEchoServer implements SerialPortEventListener sl@0: { sl@0: // Command line options sl@0: private static final String OPTION_HELP ="help"; sl@0: private static final String OPTION_PORT ="port"; sl@0: private static final String OPTION_BAUD ="baud_rate"; sl@0: private static final String OPTION_DATA ="data_bits"; sl@0: private static final String OPTION_STOP ="stop_bits"; sl@0: private static final String OPTION_PARITY ="parity"; sl@0: private static final String OPTION_FLOW ="flow_control"; sl@0: sl@0: // Default settings for serial port sl@0: private static final String DEFAULT_PORT_NAME = "COM1"; sl@0: private static final int DEFAULT_BAUD_RATE = 9600; sl@0: private static final int DEFAULT_DATA_BITS = SerialPort.DATABITS_8; sl@0: private static final int DEFAULT_STOP_BITS = SerialPort.STOPBITS_1; sl@0: private static final int DEFAULT_PARITY = SerialPort.PARITY_NONE; sl@0: private static final int DEFAULT_FLOW_CONTROL= SerialPort.FLOWCONTROL_NONE; sl@0: sl@0: // Command format limiters sl@0: private static final byte BYTE_IGNORE = '\0'; // Null sl@0: private static final byte BYTE_CLEARBI = '\1'; // Ctrl A sl@0: private static final byte BYTE_QUERYBI = '\2'; // Ctrl B sl@0: private static final byte BYTE_RESET = '\3'; // Ctrl C sl@0: private static final byte BYTE_BLOCK_START = '['; sl@0: private static final byte BYTE_BLOCK_END = ']'; sl@0: private static final String BLOCK_ASSIGN = "="; sl@0: private static final String BLOCK_SEPERATOR = ","; sl@0: sl@0: // Supported commands sl@0: private static final String CMD_BAUD_RATE = "baud_rate"; sl@0: private static final String CMD_DATA_BITS = "data_bits"; sl@0: private static final String CMD_DELAY = "delay"; sl@0: private static final String CMD_DISCONNECT = "disconnect"; sl@0: private static final String CMD_ECHO = "echo"; sl@0: private static final String CMD_FLOW_CONTROL = "flow_control"; sl@0: private static final String CMD_LOG = "log"; sl@0: private static final String CMD_PARITY = "parity"; sl@0: private static final String CMD_STOP_BITS = "stop_bits"; sl@0: sl@0: // Supported data bits sl@0: private static final String DATA_BITS_5 = "5"; sl@0: private static final String DATA_BITS_6 = "6"; sl@0: private static final String DATA_BITS_7 = "7"; sl@0: private static final String DATA_BITS_8 = "8"; sl@0: sl@0: // Supported flow control sl@0: private static final String FLOWCONTROL_NONE = "none"; sl@0: private static final String FLOWCONTROL_RTSCTS = "rtscts"; sl@0: private static final String FLOWCONTROL_XONXOFF = "xonxoff"; sl@0: sl@0: // Supported parity sl@0: private static final String PARITY_NONE = "none"; sl@0: private static final String PARITY_EVEN = "even"; sl@0: private static final String PARITY_ODD = "odd"; sl@0: private static final String PARITY_MARK = "mark"; sl@0: private static final String PARITY_SPACE = "space"; sl@0: sl@0: // Supported stop bits sl@0: private static final String STOP_BITS_1 = "1"; sl@0: private static final String STOP_BITS_1_5 = "1.5"; sl@0: private static final String STOP_BITS_2 = "2"; sl@0: sl@0: // Constants sl@0: private static final int BUFFER_SIZE = 1024; sl@0: private static final int SLEEP_PERIOD = 200000; sl@0: sl@0: private enum EStatus sl@0: { sl@0: EStatusEcho, sl@0: EStatusCommandStart, sl@0: }; sl@0: sl@0: private Thread iMainThread; sl@0: private int iRestartingDelay; sl@0: private boolean iRestarting; sl@0: private boolean iRunning; sl@0: private Logger iLogger; sl@0: private byte[] iBuffer; sl@0: private EStatus iStatus; sl@0: private String iCommand; sl@0: private String iPortName; sl@0: private byte iBI; sl@0: sl@0: private int iBaudRate; sl@0: private int iDataBits; sl@0: private int iStopBits; sl@0: private int iParity; sl@0: private int iFlowControl; sl@0: sl@0: private int iStartupBaudRate; sl@0: private int iStartupDataBits; sl@0: private int iStartupStopBits; sl@0: private int iStartupParity; sl@0: private int iStartupFlowControl; sl@0: sl@0: private CommPortIdentifier iPortIdentifier; sl@0: private SerialPort iSerialPort; sl@0: sl@0: /* sl@0: * Constructor sl@0: */ sl@0: protected UartEchoServer() throws Exception sl@0: { sl@0: iRestartingDelay=0; sl@0: iRestarting=true; sl@0: iRunning=true; sl@0: iLogger=Logger.getLogger("UartEchoServer"); sl@0: iBuffer=new byte[BUFFER_SIZE]; sl@0: iStatus = EStatus.EStatusEcho; sl@0: iCommand = ""; sl@0: iBI=0; sl@0: iPortName=DEFAULT_PORT_NAME; sl@0: iBaudRate=DEFAULT_BAUD_RATE; sl@0: iDataBits=DEFAULT_DATA_BITS; sl@0: iStopBits=DEFAULT_STOP_BITS; sl@0: iParity=DEFAULT_PARITY; sl@0: iFlowControl=DEFAULT_FLOW_CONTROL; sl@0: } sl@0: sl@0: /* sl@0: * Second pahse constructor sl@0: * sl@0: * @param aCommandLine Command line parameters sl@0: */ sl@0: protected void Construct(final CommandLine aCommandLine) throws Exception sl@0: { sl@0: /* sl@0: * Set port name if passed in command line sl@0: */ sl@0: if ( aCommandLine.hasOption(OPTION_PORT) ) sl@0: { sl@0: iPortName=aCommandLine.getOptionValue(OPTION_PORT); sl@0: iLogger.info("PortName:" + iPortName); sl@0: } sl@0: sl@0: /* sl@0: * Set baud rate if passed in command line sl@0: */ sl@0: if ( aCommandLine.hasOption(OPTION_BAUD) ) sl@0: { sl@0: setBaudRate(aCommandLine.getOptionValue(OPTION_BAUD)); sl@0: iLogger.info("Baud Rate:" + iBaudRate); sl@0: } sl@0: sl@0: /* sl@0: * Set data bits if passed in command line sl@0: */ sl@0: if ( aCommandLine.hasOption(OPTION_DATA) ) sl@0: { sl@0: setDataBits(aCommandLine.getOptionValue(OPTION_DATA)); sl@0: iLogger.info("Data Bits:" + iDataBits); sl@0: } sl@0: sl@0: /* sl@0: * Set stop bits if passed in command line sl@0: */ sl@0: if ( aCommandLine.hasOption(OPTION_STOP) ) sl@0: { sl@0: setStopBits(aCommandLine.getOptionValue(OPTION_STOP)); sl@0: iLogger.info("Stop Bits:" + iStopBits); sl@0: } sl@0: sl@0: /* sl@0: * Set parity if passed in command line sl@0: */ sl@0: if ( aCommandLine.hasOption(OPTION_PARITY) ) sl@0: { sl@0: setParity(aCommandLine.getOptionValue(OPTION_PARITY)); sl@0: iLogger.info("Parity:" + iParity); sl@0: } sl@0: sl@0: /* sl@0: * Set flow control if passed in command line sl@0: */ sl@0: if ( aCommandLine.hasOption(OPTION_FLOW) ) sl@0: { sl@0: setFlowControl(aCommandLine.getOptionValue(OPTION_FLOW)); sl@0: iLogger.info("Flow Control:" + iFlowControl); sl@0: } sl@0: sl@0: /* sl@0: * Save startup values. Used by reset command sl@0: */ sl@0: iStartupBaudRate=iBaudRate; sl@0: iStartupDataBits=iDataBits; sl@0: iStartupStopBits=iStopBits; sl@0: iStartupParity=iParity; sl@0: iStartupFlowControl=iFlowControl; sl@0: sl@0: /* sl@0: * Make sure port is not in use sl@0: */ sl@0: iPortIdentifier=CommPortIdentifier.getPortIdentifier(iPortName); sl@0: if ( iPortIdentifier.isCurrentlyOwned() ) sl@0: { sl@0: throw new Exception("Error: Port is currently in use"); sl@0: } sl@0: sl@0: /* sl@0: * Port not in use so open it sl@0: */ sl@0: CommPort commPort=iPortIdentifier.open(this.getClass().getName(), 2000); sl@0: sl@0: /* sl@0: * Save thread sl@0: */ sl@0: iMainThread=Thread.currentThread(); sl@0: sl@0: /* sl@0: * Make sure the port is of type serial sl@0: */ sl@0: if ( commPort instanceof SerialPort ) sl@0: { sl@0: iSerialPort = (SerialPort) commPort; sl@0: iFlowControl=iSerialPort.getFlowControlMode(); sl@0: while ( iRunning ) sl@0: { sl@0: initPort(); sl@0: sl@0: iRestarting=false; sl@0: while ( iRunning && !iRestarting ) sl@0: { sl@0: try sl@0: { sl@0: iMainThread.sleep(SLEEP_PERIOD); sl@0: } sl@0: catch ( InterruptedException e ) sl@0: { sl@0: } sl@0: } sl@0: iSerialPort.close(); sl@0: if ( iRestarting ) sl@0: { sl@0: iLogger.finest("Restarting"); sl@0: iMainThread.sleep(iRestartingDelay); sl@0: commPort=iPortIdentifier.open(this.getClass().getName(), 2000); sl@0: iSerialPort = (SerialPort) commPort; sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: throw new Exception("Error: Only serial ports are handled by this example."); sl@0: } sl@0: } sl@0: sl@0: /* sl@0: * Initialise the port sl@0: */ sl@0: private void initPort() throws Exception sl@0: { sl@0: iSerialPort.setSerialPortParams(iBaudRate, iDataBits, iStopBits, iParity); sl@0: iSerialPort.setFlowControlMode(iFlowControl); sl@0: iSerialPort.addEventListener(this); sl@0: iSerialPort.notifyOnBreakInterrupt(true); sl@0: iSerialPort.notifyOnCarrierDetect(true); sl@0: iSerialPort.notifyOnCTS(true); sl@0: iSerialPort.notifyOnDataAvailable(true); sl@0: iSerialPort.notifyOnDSR(true); sl@0: iSerialPort.notifyOnFramingError(true); sl@0: iSerialPort.notifyOnOutputEmpty(true); sl@0: iSerialPort.notifyOnOverrunError(true); sl@0: iSerialPort.notifyOnParityError(true); sl@0: iSerialPort.notifyOnRingIndicator(true); sl@0: iSerialPort.setInputBufferSize(BUFFER_SIZE); sl@0: } sl@0: sl@0: /* sl@0: * Set the baud rate sl@0: * sl@0: * @param aValue String representation of the baud rate sl@0: */ sl@0: private void setBaudRate(final String aValue) sl@0: { sl@0: try sl@0: { sl@0: iBaudRate=Integer.parseInt(aValue); sl@0: } sl@0: catch (Exception e) sl@0: { sl@0: iLogger.severe("convertToBaudRate(" + aValue + "):exception" + e); sl@0: } sl@0: } sl@0: sl@0: /* sl@0: * Set the data bits sl@0: * sl@0: * @param aValue String representation of the data bits sl@0: */ sl@0: private void setDataBits(final String aValue) sl@0: { sl@0: try sl@0: { sl@0: if ( aValue.compareTo(DATA_BITS_5)==0 ) sl@0: { sl@0: iDataBits=SerialPort.DATABITS_5; sl@0: } sl@0: else if ( aValue.compareTo(DATA_BITS_6)==0 ) sl@0: { sl@0: iDataBits=SerialPort.DATABITS_6; sl@0: } sl@0: else if ( aValue.compareTo(DATA_BITS_7)==0 ) sl@0: { sl@0: iDataBits=SerialPort.DATABITS_7; sl@0: } sl@0: else if ( aValue.compareTo(DATA_BITS_8)==0 ) sl@0: { sl@0: iDataBits=SerialPort.DATABITS_8; sl@0: } sl@0: else sl@0: { sl@0: iLogger.severe("setDataBits(" + aValue + ")"); sl@0: } sl@0: } sl@0: catch (Exception e) sl@0: { sl@0: iLogger.severe("setDataBits(" + aValue + "):excpetion" + e); sl@0: } sl@0: } sl@0: sl@0: /* sl@0: * Set the flow control sl@0: * sl@0: * @param aValue String representation of the flow control sl@0: */ sl@0: private void setFlowControl(final String aValue) sl@0: { sl@0: try sl@0: { sl@0: if ( aValue.compareTo(FLOWCONTROL_NONE)==0 ) sl@0: { sl@0: iFlowControl=SerialPort.FLOWCONTROL_NONE; sl@0: } sl@0: else if ( aValue.compareTo(FLOWCONTROL_RTSCTS)==0 ) sl@0: { sl@0: iFlowControl=SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT; sl@0: } sl@0: else if ( aValue.compareTo(FLOWCONTROL_XONXOFF)==0 ) sl@0: { sl@0: iFlowControl=SerialPort.FLOWCONTROL_XONXOFF_IN | SerialPort.FLOWCONTROL_XONXOFF_OUT; sl@0: } sl@0: else sl@0: { sl@0: iLogger.severe("setFlowControl(" + aValue + ")"); sl@0: } sl@0: } sl@0: catch (Exception e) sl@0: { sl@0: iLogger.severe("setFlowControl(" + aValue + "):exception" + e); sl@0: } sl@0: } sl@0: sl@0: /* sl@0: * Set the parity sl@0: * sl@0: * @param aValue String representation of the parity sl@0: */ sl@0: private void setParity(final String aValue) sl@0: { sl@0: try sl@0: { sl@0: if ( aValue.compareTo(PARITY_NONE)==0 ) sl@0: { sl@0: iParity=SerialPort.PARITY_NONE; sl@0: } sl@0: else if ( aValue.compareTo(PARITY_EVEN)==0 ) sl@0: { sl@0: iParity=SerialPort.PARITY_EVEN; sl@0: } sl@0: else if ( aValue.compareTo(PARITY_ODD)==0 ) sl@0: { sl@0: iParity=SerialPort.PARITY_ODD; sl@0: } sl@0: else if ( aValue.compareTo(PARITY_MARK)==0 ) sl@0: { sl@0: iParity=SerialPort.PARITY_MARK; sl@0: } sl@0: else if ( aValue.compareTo(PARITY_SPACE)==0 ) sl@0: { sl@0: iParity=SerialPort.PARITY_SPACE; sl@0: } sl@0: else sl@0: { sl@0: iLogger.severe("setParity(" + aValue + ")"); sl@0: } sl@0: } sl@0: catch (Exception e) sl@0: { sl@0: iLogger.severe("setParity(" + aValue + "):exception" + e); sl@0: } sl@0: } sl@0: sl@0: /* sl@0: * Set the stop bits sl@0: * sl@0: * @param aValue String representation of the stop bits sl@0: */ sl@0: private void setStopBits(final String aValue) sl@0: { sl@0: try sl@0: { sl@0: if ( aValue.compareTo(STOP_BITS_1)==0 ) sl@0: { sl@0: iStopBits=SerialPort.STOPBITS_1; sl@0: } sl@0: else if ( aValue.compareTo(STOP_BITS_1_5)==0 ) sl@0: { sl@0: iStopBits=SerialPort.STOPBITS_1_5; sl@0: } sl@0: else if ( aValue.compareTo(STOP_BITS_2)==0 ) sl@0: { sl@0: iStopBits=SerialPort.STOPBITS_2; sl@0: } sl@0: else sl@0: { sl@0: iLogger.severe("setStopBits(" + aValue + ")"); sl@0: } sl@0: } sl@0: catch (Exception e) sl@0: { sl@0: iLogger.severe("setStopBits(" + aValue + "):exception" + e); sl@0: } sl@0: } sl@0: sl@0: /* sl@0: * Process a command from the input sl@0: */ sl@0: private void processCommand() throws Exception sl@0: { sl@0: final String values[] = iCommand.split(BLOCK_SEPERATOR); sl@0: sl@0: iSerialPort.getOutputStream().flush(); sl@0: for ( int i=0; i> " + buffer); sl@0: for ( int index=0; index0 ) sl@0: { sl@0: processInput(length); sl@0: } sl@0: } sl@0: catch (Exception e) sl@0: { sl@0: e.printStackTrace(); sl@0: } sl@0: if ( iRestarting ) sl@0: { sl@0: iMainThread.interrupt(); sl@0: } sl@0: break; sl@0: case SerialPortEvent.BI: sl@0: /* sl@0: * Increment break interrupt count sl@0: */ sl@0: ++iBI; sl@0: iLogger.finest("Break Interrupt"); sl@0: break; sl@0: case SerialPortEvent.CD: sl@0: /* sl@0: * Ignore sl@0: */ sl@0: iLogger.finest("Carrier Detect"); sl@0: break; sl@0: case SerialPortEvent.CTS: sl@0: /* sl@0: * Ignore sl@0: */ sl@0: iLogger.finest("Clear To Send"); sl@0: break; sl@0: case SerialPortEvent.DSR: sl@0: /* sl@0: * Ignore sl@0: */ sl@0: iLogger.finest("Data Set Ready"); sl@0: break; sl@0: case SerialPortEvent.FE: sl@0: /* sl@0: * Ignore sl@0: */ sl@0: iLogger.finest("Framing Error"); sl@0: break; sl@0: case SerialPortEvent.OE: sl@0: /* sl@0: * Ignore sl@0: */ sl@0: iLogger.finest("Overflow Error"); sl@0: break; sl@0: case SerialPortEvent.OUTPUT_BUFFER_EMPTY: sl@0: /* sl@0: * Ignore sl@0: */ sl@0: iLogger.finest("Output Buffer Empty"); sl@0: break; sl@0: case SerialPortEvent.PE: sl@0: /* sl@0: * Ignore sl@0: */ sl@0: iLogger.finest("Parity Error"); sl@0: break; sl@0: case SerialPortEvent.RI: sl@0: /* sl@0: * Ignore sl@0: */ sl@0: iLogger.finest("Ring Interrupt"); sl@0: break; sl@0: default: sl@0: iLogger.finest("Unknown event"); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: /* sl@0: * Application entry point sl@0: * sl@0: * @param aArgs COmmand line arguments sl@0: */ sl@0: public static void main(String[] aArgs) sl@0: { sl@0: final Options options = new Options(); sl@0: sl@0: options.addOption(new Option(OPTION_HELP, "print this message")); sl@0: sl@0: OptionBuilder.withLongOpt(OPTION_PORT); sl@0: OptionBuilder.withDescription("set port COMx"); sl@0: OptionBuilder.withValueSeparator( '=' ); sl@0: OptionBuilder.hasArg(); sl@0: options.addOption(OptionBuilder.create()); sl@0: sl@0: OptionBuilder.withLongOpt(OPTION_BAUD); sl@0: OptionBuilder.withDescription("set the baud rate"); sl@0: OptionBuilder.withValueSeparator( '=' ); sl@0: OptionBuilder.hasArg(); sl@0: options.addOption(OptionBuilder.create()); sl@0: sl@0: OptionBuilder.withLongOpt(OPTION_DATA); sl@0: OptionBuilder.withDescription("set the data bits [" + DATA_BITS_5 +"|" + DATA_BITS_6 + "|" + DATA_BITS_7 + "|" + DATA_BITS_8 + "]"); sl@0: OptionBuilder.withValueSeparator( '=' ); sl@0: OptionBuilder.hasArg(); sl@0: options.addOption(OptionBuilder.create()); sl@0: sl@0: OptionBuilder.withLongOpt(OPTION_STOP); sl@0: OptionBuilder.withDescription("set the stop bits [" + STOP_BITS_1 + "|" + STOP_BITS_1_5 + "|" + STOP_BITS_2 + "]"); sl@0: OptionBuilder.withValueSeparator( '=' ); sl@0: OptionBuilder.hasArg(); sl@0: options.addOption(OptionBuilder.create()); sl@0: sl@0: OptionBuilder.withLongOpt(OPTION_PARITY); sl@0: OptionBuilder.withDescription("set the parity [" + PARITY_NONE + "|" + PARITY_EVEN + "|" + PARITY_ODD + "|" + PARITY_MARK + "|" + PARITY_SPACE + "]"); sl@0: OptionBuilder.withValueSeparator( '=' ); sl@0: OptionBuilder.hasArg(); sl@0: options.addOption(OptionBuilder.create()); sl@0: sl@0: OptionBuilder.withLongOpt(OPTION_FLOW); sl@0: OptionBuilder.withDescription("set the flow control [" + FLOWCONTROL_NONE + "|" + FLOWCONTROL_RTSCTS + "|" + FLOWCONTROL_XONXOFF + "]"); sl@0: OptionBuilder.withValueSeparator( '=' ); sl@0: OptionBuilder.hasArg(); sl@0: options.addOption(OptionBuilder.create()); sl@0: sl@0: final CommandLineParser parser = new PosixParser(); sl@0: sl@0: try sl@0: { sl@0: // parse the command line arguments sl@0: final CommandLine commandLine = parser.parse(options, aArgs); sl@0: sl@0: if ( commandLine.hasOption(OPTION_HELP) ) sl@0: { sl@0: final HelpFormatter formatter = new HelpFormatter(); sl@0: formatter.printHelp("UartEchoServer", options); sl@0: } sl@0: else sl@0: { sl@0: final UartEchoServer echoServer=new UartEchoServer(); sl@0: echoServer.Construct(commandLine); sl@0: } sl@0: } sl@0: catch ( Exception e ) sl@0: { sl@0: e.printStackTrace(); sl@0: } sl@0: } sl@0: }