001package jmri.jmrix.qsi.serialdriver; 002 003import java.io.DataInputStream; 004import java.io.DataOutputStream; 005import java.io.IOException; 006import java.io.InputStream; 007 008import jmri.jmrix.qsi.QsiPortController; 009import jmri.jmrix.qsi.QsiSystemConnectionMemo; 010import jmri.jmrix.qsi.QsiTrafficController; 011 012import org.slf4j.Logger; 013import org.slf4j.LoggerFactory; 014 015import jmri.jmrix.purejavacomm.CommPortIdentifier; 016import jmri.jmrix.purejavacomm.NoSuchPortException; 017import jmri.jmrix.purejavacomm.PortInUseException; 018import jmri.jmrix.purejavacomm.UnsupportedCommOperationException; 019 020/** 021 * Implements SerialPortAdapter for the QSI system. 022 * <p> 023 * This connects an QSI command station via a serial com port. Also used for the 024 * USB QSI, which appears to the computer as a serial port. Normally controlled 025 * by the SerialDriverFrame class. 026 * <p> 027 * The current implementation only handles the 19,200 baud rate, and does not 028 * use any other options at configuration time. 029 * 030 * @author Bob Jacobsen Copyright (C) 2001, 2002 031 */ 032public class SerialDriverAdapter extends QsiPortController { 033 034 public SerialDriverAdapter() { 035 super(new QsiSystemConnectionMemo()); 036 this.manufacturerName = jmri.jmrix.qsi.QSIConnectionTypeList.QSI; 037 } 038 039 jmri.jmrix.purejavacomm.SerialPort activeSerialPort = null; 040 041 @Override 042 public String openPort(String portName, String appName) { 043 // open the port, check ability to set moderators 044 try { 045 // get and open the primary port 046 CommPortIdentifier portID = CommPortIdentifier.getPortIdentifier(portName); 047 try { 048 activeSerialPort = portID.open(appName, 2000); // name of program, msec to wait 049 } catch (PortInUseException p) { 050 return handlePortBusy(p, portName, log); 051 } 052 053 // try to set it for communication via SerialDriver 054 try { 055 activeSerialPort.setSerialPortParams(19200, 056 jmri.jmrix.purejavacomm.SerialPort.DATABITS_8, 057 jmri.jmrix.purejavacomm.SerialPort.STOPBITS_1, 058 jmri.jmrix.purejavacomm.SerialPort.PARITY_NONE); 059 } catch (UnsupportedCommOperationException e) { 060 log.error("Cannot set serial parameters on port {}: {}", portName, e.getMessage()); 061 return "Cannot set serial parameters on port " + portName + ": " + e.getMessage(); 062 } 063 064 // disable flow control; hardware lines used for signaling, XON/XOFF might appear in data 065 configureLeadsAndFlowControl(activeSerialPort, 0); 066 067 // set timeout 068 // activeSerialPort.enableReceiveTimeout(1000); 069 log.debug("Serial timeout was observed as: {} {}", activeSerialPort.getReceiveTimeout(), 070 activeSerialPort.isReceiveTimeoutEnabled()); 071 072 // get and save stream 073 serialStream = activeSerialPort.getInputStream(); 074 075 // purge contents, if any 076 purgeStream(serialStream); 077 078 // report status? 079 if (log.isInfoEnabled()) { 080 log.info("{} port opened at {} baud, sees DTR: {} RTS: {} DSR: {} CTS: {} CD: {}", portName, activeSerialPort.getBaudRate(), activeSerialPort.isDTR(), activeSerialPort.isRTS(), activeSerialPort.isDSR(), activeSerialPort.isCTS(), activeSerialPort.isCD()); 081 } 082 opened = true; 083 084 } catch (NoSuchPortException p) { 085 return handlePortNotFound(p, portName, log); 086 } catch (IOException ex) { 087 log.error("Unexpected exception while opening port {}", portName, ex); 088 return "Unexpected error while opening port " + portName + ": " + ex; 089 } 090 return null; // indicates OK return 091 } 092 093 public void setHandshake(int mode) { 094 try { 095 activeSerialPort.setFlowControlMode(mode); 096 } catch (UnsupportedCommOperationException ex) { 097 log.error("Unexpected exception while setting COM port handshake mode", ex); 098 } 099 } 100 101 /** 102 * Set up all of the other objects to operate with an QSI command station 103 * connected to this port 104 */ 105 @Override 106 public void configure() { 107 108 this.getSystemConnectionMemo().setQsiTrafficController(new QsiTrafficController()); 109 // connect to the traffic controller 110 this.getSystemConnectionMemo().getQsiTrafficController().connectPort(this); 111 112 this.getSystemConnectionMemo().configureManagers(); 113 114 sinkThread = new Thread(this.getSystemConnectionMemo().getQsiTrafficController()); 115 sinkThread.start(); 116 117 // jmri.InstanceManager.setThrottleManager(new jmri.jmrix.qsi.QsiThrottleManager()); 118 } 119 120 private Thread sinkThread; 121 122 // base class methods for the QsiPortController interface 123 @Override 124 public DataInputStream getInputStream() { 125 if (!opened) { 126 log.error("getInputStream called before load(), stream not available"); 127 return null; 128 } 129 return new DataInputStream(serialStream); 130 } 131 132 @Override 133 public DataOutputStream getOutputStream() { 134 if (!opened) { 135 log.error("getOutputStream called before load(), stream not available"); 136 } 137 try { 138 return new DataOutputStream(activeSerialPort.getOutputStream()); 139 } catch (java.io.IOException e) { 140 log.error("getOutputStream exception: ", e); 141 } 142 return null; 143 } 144 145 @Override 146 public boolean status() { 147 return opened; 148 } 149 150 /** 151 * {@inheritDoc} 152 * 153 * Currently only 19,200 bps 154 */ 155 @Override 156 public String[] validBaudRates() { 157 return new String[]{"19,200 bps"}; 158 } 159 160 /** 161 * {@inheritDoc} 162 */ 163 @Override 164 public int[] validBaudNumbers() { 165 return new int[]{19200}; 166 } 167 168 @Override 169 public int defaultBaudIndex() { 170 return 0; 171 } 172 173 private boolean opened = false; 174 InputStream serialStream = null; 175 176 private final static Logger log = LoggerFactory.getLogger(SerialDriverAdapter.class); 177 178}