001package jmri.jmrix.sprog;
002
003import java.io.DataInputStream;
004import java.io.DataOutputStream;
005import jmri.jmrix.AbstractStreamPortController;
006import jmri.jmrix.sprog.SprogConstants.SprogMode;
007import org.slf4j.Logger;
008import org.slf4j.LoggerFactory;
009
010/**
011 * Abstract base for classes representing an SPROG Command Station
012 * communications port
013 * <p>
014 * NOTE: This currently only supports the SPROG Command Station interfaces.
015 *
016 * @author Paul Bender Copyright (C) 2014
017 */
018public class SprogCSStreamPortController extends AbstractStreamPortController implements SprogInterface {
019
020    private Thread rcvNotice = null;
021    private SprogMode operatingMode = SprogMode.OPS;
022
023    public SprogCSStreamPortController(DataInputStream in, DataOutputStream out, String pname) {
024        super(new SprogSystemConnectionMemo(SprogConstants.SprogMode.OPS), in, out, pname);
025    }
026
027    public SprogCSStreamPortController() {
028        super(new SprogSystemConnectionMemo(SprogConstants.SprogMode.OPS));
029    }
030
031    @Override
032    public void configure() {
033        log.debug("configure() called.");
034        SprogTrafficController control = new SprogTrafficController(this.getSystemConnectionMemo());
035
036        this.getSystemConnectionMemo().setSprogMode(operatingMode); // first update mode in memo
037
038        // connect to the traffic controller
039        this.getSystemConnectionMemo().setSprogTrafficController(control);
040        control.setAdapterMemo(this.getSystemConnectionMemo());
041        this.getSystemConnectionMemo().configureCommandStation();
042        this.getSystemConnectionMemo().configureManagers();
043        control.connectPort(this);
044
045        // start thread to notify controller when data is available
046        rcvNotice = new Thread(new RcvCheck(input, control));
047        rcvNotice.setName("SPROG Stream Port Controller Receive thread");
048        rcvNotice.start();
049    }
050
051    /**
052     * Check that this object is ready to operate. This is a question of
053     * configuration, not transient hardware status.
054     */
055    @Override
056    public boolean status() {
057        return true;
058    }
059
060    /**
061     * Can the port accept additional characters?
062     *
063     * @return true
064     */
065    public boolean okToSend() {
066        return (true);
067    }
068
069    // SPROG Interface methods.
070    @Override
071    public void addSprogListener(SprogListener l) {
072        this.getSystemConnectionMemo().getSprogTrafficController().addSprogListener(l);
073    }
074
075    @Override
076    public void removeSprogListener(SprogListener l) {
077        this.getSystemConnectionMemo().getSprogTrafficController().removeSprogListener(l);
078    }
079
080    @Override
081    public void sendSprogMessage(SprogMessage m, SprogListener l) {
082        this.getSystemConnectionMemo().getSprogTrafficController().sendSprogMessage(m, l);
083    }
084
085    @Override
086    public SprogSystemConnectionMemo getSystemConnectionMemo() {
087        return (SprogSystemConnectionMemo) super.getSystemConnectionMemo();
088    }
089
090    // internal thread to check to see if the stream has data and
091    // notify the Traffic Controller.
092    static protected class RcvCheck implements Runnable {
093
094        private SprogTrafficController control;
095        private DataInputStream in;
096
097        public RcvCheck(DataInputStream in, SprogTrafficController control) {
098            this.in = in;
099            this.control = control;
100        }
101
102        @Override
103        public void run() {
104            do {
105                try {
106                    if (in.available() > 0) {
107                        control.handleOneIncomingReply();
108                    }
109                } catch (java.io.IOException ioe) {
110                    log.error("Error reading data from stream");
111                }
112                // need to sleep here?
113            } while (true);
114        }
115    }
116
117    private final static Logger log = LoggerFactory.getLogger(SprogCSStreamPortController.class);
118
119}