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     * Provide the maximum number of dimming steps available.
074     *
075     * @return By default, dimming not available.
076     */
077    public int getNumberOfIntensitySteps() {
078        return 0;
079    }
080
081    /**
082     * Get a message of a specific length for filling in.
083     * <p>
084     * This is a default, null implementation, which must be overridden in an
085     * adapter-specific subclass.
086     *
087     * @param length message size
088     * @return null
089     */
090    public SerialMessage getSerialMessage(int length) {
091        return null;
092    }
093
094    // have several debug statements in tight loops, e.g. every character;
095    // only want to check once
096    protected boolean logDebug = false;
097
098    // The methods to implement the SerialInterface
099    @Override
100    public synchronized void addSerialListener(SerialListener l) {
101        this.addListener(l);
102    }
103
104    @Override
105    public synchronized void removeSerialListener(SerialListener l) {
106        this.removeListener(l);
107    }
108
109    @Override
110    protected int enterProgModeDelayTime() {
111        // we should to wait at least a second after enabling the programming track
112        return 1000;
113    }
114
115    /**
116     * Forward a SerialMessage to all registered SerialInterface listeners.
117     */
118    @Override
119    protected void forwardMessage(AbstractMRListener client, AbstractMRMessage m) {
120        ((SerialListener) client).message((SerialMessage) m);
121    }
122
123    /**
124     * Forward a reply to all registered SerialInterface listeners.
125     */
126    @Override
127    protected void forwardReply(AbstractMRListener client, AbstractMRReply r) {
128        ((SerialListener) client).reply((SerialReply) r);
129    }
130
131    SerialSensorManager mSensorManager = null;
132
133    public void setSensorManager(SerialSensorManager m) {
134        mSensorManager = m;
135    }
136
137    public SerialSensorManager getSensorManager() {
138        return mSensorManager;
139    }
140
141    /**
142     * Eventually, do initialization if needed
143     */
144    @Override
145    protected AbstractMRMessage pollMessage() {
146        return null;
147    }
148
149    @Override
150    protected AbstractMRListener pollReplyHandler() {
151        return null;
152    }
153
154    /**
155     * Forward a preformatted message to the actual interface.
156     */
157    @Override
158    public void sendSerialMessage(SerialMessage m, SerialListener reply) {
159        sendMessage(m, reply);
160    }
161
162    @Override
163    protected void forwardToPort(AbstractMRMessage m, AbstractMRListener reply) {
164        if (logDebug) {
165            log.debug("forward {}", m);
166        }
167        sendInterlock = ((SerialMessage) m).getInterlocked();
168        super.forwardToPort(m, reply);
169    }
170
171    @Override
172    protected AbstractMRMessage enterProgMode() {
173        return null;
174    }
175
176    @Override
177    protected AbstractMRMessage enterNormalMode() {
178        return null;
179    }
180
181    public void setAdapterMemo(SerialSystemConnectionMemo adaptermemo) {
182        memo = adaptermemo;
183    }
184
185    public SerialSystemConnectionMemo getAdapterMemo() {
186        return memo;
187    }
188
189    protected SerialSystemConnectionMemo memo = null;
190    SerialTrafficController self = null;
191
192    boolean sendInterlock = false; // send the 00 interlock when CRC received
193    boolean expectLength = false;  // next byte is length of read
194    boolean countingBytes = false; // counting remainingBytes into reply buffer
195    int remainingBytes = 0;        // count of bytes _left_
196
197    /**
198     * This is a default, null implementation, which must be overridden in an
199     * adapter-specific subclass.
200     */
201    @Override
202    protected boolean endOfMessage(AbstractMRReply msg) {
203        return true;
204    }
205
206    /**
207     * This is a default, null implementation, which must be overridden in an
208     * adapter-specific subclass.
209     */
210    @Override
211    protected AbstractMRReply newReply() {
212        return null;
213    }
214
215    private final static Logger log = LoggerFactory.getLogger(SerialTrafficController.class);
216
217}