001package jmri.jmrix.zimo;
002
003import java.util.Vector;
004import org.slf4j.Logger;
005import org.slf4j.LoggerFactory;
006
007/**
008 * Abstract base class for implementations of MX-1 Interface.
009 * <p>
010 * This provides just the basic interface, plus the "" static method for
011 * locating the local implementation.
012 * <p>
013 * Adapted by Sip Bosch for use with zimo Mx-1.
014 * 
015 * @author Bob Jacobsen Copyright (C) 2002
016 */
017public abstract class Mx1TrafficController implements Mx1Interface {
018
019    /**
020     * Create a new TrafficController instance. Simple implementation.
021     */
022    public Mx1TrafficController() {
023        super();
024    }
025
026    /**
027     * Must provide a ZimoCommandStation reference at creation time
028     *
029     * @param pCommandStation reference to associated command station object,
030     *                        preserved for later.
031     * @param prot            false if {@link #ASCII}, true if {@link #BINARY}
032     */
033    Mx1TrafficController(Mx1CommandStation pCommandStation, boolean prot) {
034        mCommandStation = pCommandStation;
035        protocol = prot;
036    }
037
038    public final static boolean ASCII = false;
039    public final static boolean BINARY = true;
040
041    boolean protocol = ASCII;
042
043    public boolean getProtocol() {
044        return protocol;
045    }
046
047    // Abstract methods for the Mx1Interface
048    @Override
049    abstract public boolean status();
050
051    /**
052     * Forward a pre-formatted Mx1Message to the actual interface.
053     *
054     * @param m     Message to send; will be updated with CRC
055     * @param reply the listener to notify of a response
056     */
057    @Override
058    abstract public void sendMx1Message(Mx1Message m, Mx1Listener reply);
059
060    // The methods to implement adding and removing listeners
061    protected Vector<Mx1Listener> listeners = new Vector<>();
062
063    @Override
064    public synchronized void addMx1Listener(int mask, Mx1Listener l) {
065        // add only if not already registered
066        if (l == null) {
067            throw new java.lang.NullPointerException();
068        }
069        if (!listeners.contains(l)) {
070            listeners.addElement(l);
071        }
072    }
073
074    @Override
075    public synchronized void removeMx1Listener(int mask, Mx1Listener l) {
076        if (listeners.contains(l)) {
077            listeners.removeElement(l);
078        }
079    }
080
081    /**
082     * Forward a message to all registered listeners.
083     *
084     * @param m       Message to forward. Listeners should not modify it!
085     * @param replyTo Listener for the reply to this message, doesn't get the
086     *                echo of it.
087     */
088    @SuppressWarnings("unchecked")
089    protected void notify(Mx1Message m, Mx1Listener replyTo) {
090        // make a copy of the listener vector to synchronized not needed for transmit
091        Vector<Mx1Listener> v;
092        synchronized (this) {
093            v = (Vector<Mx1Listener>) listeners.clone();
094        }
095        if (log.isDebugEnabled()) {
096            log.debug("notify of incoming packet: {}", m.toString());
097        }
098        // forward to all listeners
099        int cnt = v.size();
100        for (int i = 0; i < cnt; i++) {
101            Mx1Listener client = listeners.elementAt(i);
102            if (client != replyTo) {
103                client.message(m);
104            }
105        }
106    }
107
108    /**
109     * Reference to the command station in communication here
110     */
111    Mx1CommandStation mCommandStation;
112
113    /**
114     * Get access to communicating command station object
115     *
116     * @return associated Command Station object
117     */
118    public Mx1CommandStation getCommandStation() {
119        return mCommandStation;
120    }
121
122    public Mx1SystemConnectionMemo getAdapterMemo() {
123        return adaptermemo;
124    }
125
126    public void setAdapterMemo(Mx1SystemConnectionMemo memo) {
127        adaptermemo = memo;
128    }
129
130    Mx1SystemConnectionMemo adaptermemo;
131
132    public String getUserName() {
133        if (adaptermemo == null) {
134            return "Zimo"; // NOI18N
135        }
136        return adaptermemo.getUserName();
137    }
138
139    public String getSystemPrefix() {
140        if (adaptermemo == null) {
141            return "Z"; // NOI18N
142        }
143        return adaptermemo.getSystemPrefix();
144    }
145
146    private final static Logger log = LoggerFactory.getLogger(Mx1TrafficController.class);
147
148}