001package jmri.jmrix.lenz; 002 003/** 004 * Abstract base for classes representing an XNet communications port 005 * 006 * @author Bob Jacobsen Copyright (C) 2001, 2008 007 * @author Paul Bender Copyright (C) 2004,2010 008 */ 009public abstract class XNetSerialPortController extends jmri.jmrix.AbstractSerialPortController implements XNetPortController { 010 011 private boolean outputBufferEmpty = true; 012 013 private boolean timeSlot = true; 014 015 public XNetSerialPortController() { 016 super(new XNetSystemConnectionMemo()); 017 } 018 019 public XNetSerialPortController(XNetSystemConnectionMemo memo) { 020 super(memo); 021 } 022 023 /** 024 * Can the port accept additional characters? The state of CTS determines 025 * this, as there seems to be no way to check the number of queued bytes and 026 * buffer length. This might go false for short intervals, but it might also 027 * stick off if something goes wrong. 028 */ 029 @Override 030 public boolean okToSend() { 031 if (getFlowControl(currentSerialPort) == FlowControl.RTSCTS) { 032 if (checkBuffer) { 033 log.debug("CTS: {} Buffer Empty {}",currentSerialPort.getCTS(),outputBufferEmpty); 034 return (currentSerialPort.getCTS() && outputBufferEmpty); 035 } else { 036 log.debug("CTS: {}",currentSerialPort.getCTS()); 037 return (currentSerialPort.getCTS()); 038 } 039 } else { 040 if (checkBuffer) { 041 log.debug("Buffer Empty: {}", outputBufferEmpty); 042 return (outputBufferEmpty && hasTimeSlot() ); 043 } else { 044 log.debug("No Flow Control or Buffer Check"); 045 return (hasTimeSlot()); 046 } 047 } 048 } 049 050 /** 051 * Indicate whether the Command Station is currently providing a timeslot to this 052 * port controller. 053 * 054 * @return true if the command station is currently providing a timeslot. 055 */ 056 @Override 057 public boolean hasTimeSlot(){ 058 return timeSlot; 059 } 060 061 /** 062 * Set a variable indicating whether or not the command station is 063 * providing a timeslot. 064 * <p> 065 * This method should be called with the paramter set to false if 066 * a "Command Station No Longer Providing a timeslot for communications" 067 * (01 05 04) is received. 068 * <p> 069 * This method should be called with the parameter set to true if 070 * a "Command Station is providing a timeslot for communications again." 071 * (01 07 06) is received. 072 * 073 * @param timeslot true if a timeslot is being sent, false otherwise. 074 */ 075 @Override 076 public void setTimeSlot(boolean timeslot){ 077 timeSlot = timeslot; 078 } 079 080 081 /** 082 * We need a way to say if the output buffer is empty or full. 083 * <p> 084 * This should only be set to false by external processes. 085 */ 086 @Override 087 public synchronized void setOutputBufferEmpty(boolean s) { 088 outputBufferEmpty = s; 089 } 090 091 092 /* Option 2 is not currenddtly used with RxTx 2.0. In the past, it 093 was used for the "check buffer status when sending" If this is still set 094 in a configuration file, we need to handle it, but we are not writing it 095 to new configuration files. */ 096 protected String[] validOption2 = new String[]{"yes", "no"}; 097 private boolean checkBuffer = false; 098 099 /** 100 * Allow derived classes to set the private checkBuffer value. 101 * @param b new checkBuffer value 102 */ 103 protected void setCheckBuffer(boolean b) { 104 checkBuffer = b; 105 } 106 107 @Override 108 public XNetSystemConnectionMemo getSystemConnectionMemo() { 109 return (XNetSystemConnectionMemo) super.getSystemConnectionMemo(); 110 } 111 112 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(XNetSerialPortController.class); 113 114}