001package jmri.jmrix.powerline; 002 003import jmri.jmrix.AbstractMRListener; 004import jmri.jmrix.AbstractMRMessage; 005import jmri.jmrix.AbstractMRReply; 006import jmri.jmrix.AbstractMRTrafficController; 007import org.slf4j.Logger; 008import org.slf4j.LoggerFactory; 009 010/** 011 * Converts Stream-based I/O to/from messages. The "SerialInterface" side 012 * sends/receives message objects. 013 * <p> 014 * The connection to a SerialPortController is via a pair of *Streams, which 015 * then carry sequences of characters for transmission. Note that this 016 * processing is handled in an independent thread. 017 * <p> 018 * This maintains a list of nodes, but doesn't currently do anything with it. 019 * <p> 020 * This implementation is complete and can be instantiated, but is not 021 * functional. It will be created e.g. when a default object is needed for 022 * configuring nodes, etc, during the initial configuration. A subclass must be 023 * instantiated to actually communicate with an adapter. 024 * 025 * @author Bob Jacobsen Copyright (C) 2001, 2003, 2005, 2006, 2008 Converted to 026 * multiple connection 027 * @author kcameron Copyright (C) 2011 028 */ 029abstract public class SerialTrafficController extends AbstractMRTrafficController implements SerialInterface { 030 031 /** 032 * Create a new TrafficController instance. Simple implementation. 033 */ 034 public SerialTrafficController() { 035 super(); 036 logDebug = log.isDebugEnabled(); 037 038 // not polled at all, so allow unexpected messages, and 039 // use poll delay just to spread out startup 040 setAllowUnexpectedReply(true); 041 mWaitBeforePoll = 1000; // can take a long time to send 042 } 043 044 /** 045 * Send a sequence of X10 messages to an adapter. 046 * <p> 047 * Makes them into the local messages and then queues in order. 048 * <p> 049 * This is a default, null implementation, which must be overridden in an 050 * adapter-specific subclass. 051 * 052 * @param s sequence to send 053 * @param l listener for reply 054 */ 055 public void sendX10Sequence(X10Sequence s, SerialListener l) { 056 } 057 058 /** 059 * Send a sequence of Insteon messages to an adapter. 060 * <p> 061 * Makes them into the local messages and then queues in order. 062 * <p> 063 * This is a default, null implementation, which must be overridden in an 064 * adapter-specific subclass. 065 * 066 * @param s sequence to send 067 * @param l listener for reply 068 */ 069 public void sendInsteonSequence(InsteonSequence s, SerialListener l) { 070 } 071 072 /** 073 * Send a sequence of DMX messages to an adapter. 074 * <p> 075 * Makes them into the local messages and then queues in order. 076 * <p> 077 * This is a default, null implementation, which must be overridden in an 078 * adapter-specific subclass. 079 * 080 * DMX does work with a sequence, it directly updates the data array 081 * @param unitid which light 082 * @param newStep new intesity value 083 * 084 * @return true on success 085 */ 086 public boolean sendDmxSequence(int unitid, byte newStep) { 087 return false; 088 } 089 090 /** 091 * Provide the maximum number of dimming steps available. 092 * 093 * @return By default, dimming not available. 094 */ 095 public int getNumberOfIntensitySteps() { 096 return 0; 097 } 098 099 /** 100 * Get a message of a specific length for filling in. 101 * <p> 102 * This is a default, null implementation, which must be overridden in an 103 * adapter-specific subclass. 104 * 105 * @param length message size 106 * @return null 107 */ 108 public SerialMessage getSerialMessage(int length) { 109 return null; 110 } 111 112 // have several debug statements in tight loops, e.g. every character; 113 // only want to check once 114 protected boolean logDebug = false; 115 116 // The methods to implement the SerialInterface 117 @Override 118 public synchronized void addSerialListener(SerialListener l) { 119 this.addListener(l); 120 } 121 122 @Override 123 public synchronized void removeSerialListener(SerialListener l) { 124 this.removeListener(l); 125 } 126 127 @Override 128 protected int enterProgModeDelayTime() { 129 // we should to wait at least a second after enabling the programming track 130 return 1000; 131 } 132 133 /** 134 * Forward a SerialMessage to all registered SerialInterface listeners. 135 */ 136 @Override 137 protected void forwardMessage(AbstractMRListener client, AbstractMRMessage m) { 138 ((SerialListener) client).message((SerialMessage) m); 139 } 140 141 /** 142 * Forward a reply to all registered SerialInterface listeners. 143 */ 144 @Override 145 protected void forwardReply(AbstractMRListener client, AbstractMRReply r) { 146 ((SerialListener) client).reply((SerialReply) r); 147 } 148 149 SerialSensorManager mSensorManager = null; 150 151 public void setSensorManager(SerialSensorManager m) { 152 mSensorManager = m; 153 } 154 155 public SerialSensorManager getSensorManager() { 156 return mSensorManager; 157 } 158 159 /** 160 * Eventually, do initialization if needed 161 */ 162 @Override 163 protected AbstractMRMessage pollMessage() { 164 return null; 165 } 166 167 @Override 168 protected AbstractMRListener pollReplyHandler() { 169 return null; 170 } 171 172 /** 173 * Forward a preformatted message to the actual interface. 174 */ 175 @Override 176 public void sendSerialMessage(SerialMessage m, SerialListener reply) { 177 sendMessage(m, reply); 178 } 179 180 @Override 181 protected void forwardToPort(AbstractMRMessage m, AbstractMRListener reply) { 182 if (logDebug) { 183 log.debug("forward {}", m); 184 } 185 sendInterlock = ((SerialMessage) m).getInterlocked(); 186 super.forwardToPort(m, reply); 187 } 188 189 @Override 190 protected AbstractMRMessage enterProgMode() { 191 return null; 192 } 193 194 @Override 195 protected AbstractMRMessage enterNormalMode() { 196 return null; 197 } 198 199 public void setAdapterMemo(SerialSystemConnectionMemo adaptermemo) { 200 memo = adaptermemo; 201 } 202 203 public SerialSystemConnectionMemo getAdapterMemo() { 204 return memo; 205 } 206 207 protected SerialSystemConnectionMemo memo = null; 208 SerialTrafficController self = null; 209 210 boolean sendInterlock = false; // send the 00 interlock when CRC received 211 boolean expectLength = false; // next byte is length of read 212 boolean countingBytes = false; // counting remainingBytes into reply buffer 213 int remainingBytes = 0; // count of bytes _left_ 214 215 /** 216 * This is a default, null implementation, which must be overridden in an 217 * adapter-specific subclass. 218 */ 219 @Override 220 protected boolean endOfMessage(AbstractMRReply msg) { 221 return true; 222 } 223 224 /** 225 * This is a default, null implementation, which must be overridden in an 226 * adapter-specific subclass. 227 */ 228 @Override 229 protected AbstractMRReply newReply() { 230 return null; 231 } 232 233 private final static Logger log = LoggerFactory.getLogger(SerialTrafficController.class); 234 235}