001package jmri.jmrix.powerline.simulator;
002
003import java.io.DataInputStream;
004import java.io.DataOutputStream;
005import java.io.PipedInputStream;
006import java.io.PipedOutputStream;
007
008import jmri.jmrix.powerline.SerialPortController;
009import jmri.util.ImmediatePipedOutputStream;
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013/**
014 * Implement simulator for Powerline serial systems.
015 * <p>
016 * System names are "PLnnn", where P is the user-configurable system prefix,
017 * nnn is the bit number without padding.
018 * <p>
019 * Based on the NCE simulator.
020 *
021 * @author Dave Duchamp Copyright (C) 2004
022 * @author Bob Jacobsen Copyright (C) 2006, 2007, 2008 Converted to multiple connection
023 * @author kcameron Copyright (C) 2011
024 */
025public class SimulatorAdapter extends SerialPortController implements Runnable {
026
027    // private control members
028    private Thread sourceThread;
029
030    // streams to share with user class
031    private DataOutputStream pout = null; // this is provided to classes who want to write to us
032    private DataInputStream pin = null; // this is provided to classes who want data from us
033
034    // internal ends of the pipes
035
036    //private DataOutputStream outpipe = null; // feed pin
037
038    //private DataInputStream inpipe = null; // feed pout
039
040    public SimulatorAdapter() {
041        super(new SpecificSystemConnectionMemo());
042    }
043
044    @Override
045    public String openPort(String portName, String appName) {
046        try {
047            PipedOutputStream tempPipeI = new ImmediatePipedOutputStream();
048            pout = new DataOutputStream(tempPipeI);
049            //inpipe = new DataInputStream(new PipedInputStream(tempPipeI));
050            PipedOutputStream tempPipeO = new ImmediatePipedOutputStream();
051            //outpipe = new DataOutputStream(tempPipeO);
052            pin = new DataInputStream(new PipedInputStream(tempPipeO));
053        } catch (java.io.IOException e) {
054            log.error("init (pipe): Exception: {}", e.toString());
055        }
056        opened = true;
057        return null; // indicates OK return
058    }
059
060    /**
061     * Set up all of the other objects to simulate operation with an command
062     * station.
063     */
064    @Override
065    public void configure() {
066        SpecificTrafficController tc = new SpecificTrafficController(this.getSystemConnectionMemo());
067
068        // connect to the traffic controller
069        this.getSystemConnectionMemo().setTrafficController(tc);
070        tc.setAdapterMemo(this.getSystemConnectionMemo());
071        this.getSystemConnectionMemo().configureManagers();
072        tc.connectPort(this);
073
074        // Configure the form of serial address validation for this connection
075        this.getSystemConnectionMemo().setSerialAddress(new jmri.jmrix.powerline.SerialAddress(this.getSystemConnectionMemo()));
076
077        // start the simulator
078        sourceThread = new Thread(this);
079        sourceThread.setName("Powerline Simulator");
080        sourceThread.setPriority(Thread.MIN_PRIORITY);
081        sourceThread.start();
082    }
083
084    // base class methods for the PortController interface
085    @Override
086    public DataInputStream getInputStream() {
087        if (!opened || pin == null) {
088            log.error("getInputStream called before load(), stream not available");
089        }
090        return pin;
091    }
092
093    @Override
094    public DataOutputStream getOutputStream() {
095        if (!opened || pout == null) {
096            log.error("getOutputStream called before load(), stream not available");
097        }
098        return pout;
099    }
100
101    @Override
102    public boolean status() {
103        return opened;
104    }
105
106    /**
107     * {@inheritDoc}
108     */
109    @Override
110    public String[] validBaudRates() {
111        log.debug("validBaudRates should not have been invoked");
112        return new String[]{};
113    }
114
115    /**
116     * {@inheritDoc}
117     */
118    @Override
119    public int[] validBaudNumbers() {
120        return new int[]{};
121    }
122
123    @Override
124    public String getCurrentBaudRate() {
125        return "";
126    }
127
128    @Override
129    public String getCurrentPortName(){
130        return "";
131    }
132
133    @Override
134    public void run() { // start a new thread
135        // Simulator thread just reports start and ends
136        if (log.isInfoEnabled()) {
137            log.info("Powerline Simulator Started");
138        }
139    }
140
141    private final static Logger log = LoggerFactory
142            .getLogger(SimulatorAdapter.class);
143
144}