001package jmri.jmrix.rfid;
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 "RfidInterface" 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
026 * @author Matthew Harris Copyright (C) 2011
027 * @since 2.11.4
028 */
029abstract public class RfidTrafficController extends AbstractMRTrafficController implements RfidInterface {
030
031    /**
032     * Create a new RfidTrafficController instance.
033     */
034    public RfidTrafficController() {
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    protected RfidSystemConnectionMemo adapterMemo;
046
047    public void setAdapterMemo(RfidSystemConnectionMemo memo) {
048        adapterMemo = memo;
049    }
050
051    public RfidSystemConnectionMemo getAdapterMemo() {
052        return adapterMemo;
053    }
054
055    /**
056     * Get a message of a specific length for filling in.
057     * <p>
058     * This is a default, null implementation, which must be overridden in an
059     * adapter-specific subclass.
060     * @param length message length.
061     * @return the RfidMessage.
062     */
063    public RfidMessage getRfidMessage(int length) {
064        return null;
065    }
066
067    // have several debug statements in tight loops, e.g. every character;
068    // only want to check once
069    protected boolean logDebug = false;
070
071    // The methods to implement the RfidInterface
072    @Override
073    public synchronized void addRfidListener(RfidListener l) {
074        this.addListener(l);
075    }
076
077    @Override
078    public synchronized void removeRfidListener(RfidListener l) {
079        this.removeListener(l);
080    }
081
082    /**
083     * Forward a RfidMessage to all registered RfidInterface listeners.
084     */
085    @Override
086    protected void forwardMessage(AbstractMRListener client, AbstractMRMessage m) {
087        ((RfidListener) client).message((RfidMessage) m);
088    }
089
090    /**
091     * Forward a reply to all registered RfidInterface listeners.
092     */
093    @Override
094    protected void forwardReply(AbstractMRListener client, AbstractMRReply r) {
095        ((RfidListener) client).reply((RfidReply) r);
096    }
097
098    RfidSensorManager mSensorManager = null;
099
100    public void setSensorManager(RfidSensorManager m) {
101        mSensorManager = m;
102    }
103
104    public RfidSensorManager getSensorManager() {
105        return mSensorManager;
106    }
107
108    RfidReporterManager mReporterManager = null;
109
110    public void setReporterManager(RfidReporterManager m) {
111        mReporterManager = m;
112    }
113
114    public RfidReporterManager getReporterManager() {
115        return mReporterManager;
116    }
117
118    /**
119     * Eventually, do initialization if needed
120     */
121    @Override
122    protected AbstractMRMessage pollMessage() {
123        return null;
124    }
125
126    @Override
127    protected AbstractMRListener pollReplyHandler() {
128        return null;
129    }
130
131    /**
132     * Forward a preformatted message to the actual interface.
133     */
134    @Override
135    public void sendRfidMessage(RfidMessage m, RfidListener reply) {
136        sendMessage(m, reply);
137    }
138
139    @Override
140    protected void forwardToPort(AbstractMRMessage m, AbstractMRListener reply) {
141        if (logDebug) {
142            log.debug("forward {}", m);
143        }
144        sendInterlock = ((RfidMessage) m).getInterlocked();
145        super.forwardToPort(m, reply);
146    }
147
148    @Override
149    protected AbstractMRMessage enterProgMode() {
150        return null;
151    }
152
153    @Override
154    protected AbstractMRMessage enterNormalMode() {
155        return null;
156    }
157
158    boolean sendInterlock = false; // send the 00 interlock when CRC received
159    boolean expectLength = false;  // next byte is length of read
160    boolean countingBytes = false; // counting remainingBytes into reply buffer
161    int remainingBytes = 0;        // count of bytes _left_
162
163    /**
164     * <p>
165     * This is a default, null implementation, which must be overridden in an
166     * adapter-specific subclass.
167     */
168    @Override
169    protected boolean endOfMessage(AbstractMRReply msg) {
170        return true;
171    }
172
173    /**
174     * <p>
175     * This is a default, null implementation, which must be overridden in an
176     * adapter-specific subclass.
177     */
178    @Override
179    protected AbstractMRReply newReply() {
180        return null;
181    }
182
183    abstract public void sendInitString();
184
185    public String getRange() {
186        return null;
187    }
188
189    private static final Logger log = LoggerFactory.getLogger(RfidTrafficController.class);
190}