001package jmri.jmrix.dccpp.serial;
002
003import java.util.Arrays;
004import jmri.jmrix.dccpp.DCCppCommandStation;
005import jmri.jmrix.dccpp.DCCppInitializationManager;
006import jmri.jmrix.dccpp.DCCppSerialPortController;
007import jmri.jmrix.dccpp.DCCppTrafficController;
008
009/**
010 * Provide access to DCC++ via a FTDI Virtual Com Port.
011 *
012 * @author Mark Underwood Copyright (C) 2015
013 *
014 * Based on jmri.jmirx.lenz.liusb.LIUSBAdapter by Paul Bender
015 */
016public class DCCppAdapter extends DCCppSerialPortController {
017
018    public DCCppAdapter() {
019        super();
020        option1Name = "StartUpDelay";
021        options.put(option1Name, new Option("Wait at startup : ", validStartupDelays));
022        this.manufacturerName = jmri.jmrix.dccpp.DCCppConnectionTypeList.DCCPP;
023    }
024
025    @Override
026    public String openPort(String portName, String appName) {
027        // get and open the primary port
028        currentSerialPort = activatePort(portName, log);
029        if (currentSerialPort == null) {
030            log.error("failed to connect DCC++ to {}", portName);
031            return Bundle.getMessage("SerialPortNotFound", portName);
032        }
033        log.info("Connecting DCC++ to {} {}", portName, currentSerialPort);
034
035        // try to set it for communication via SerialDriver
036        // find the baud rate value, configure comm options
037        int baud = currentBaudNumber(mBaudRate);
038        setBaudRate(currentSerialPort, baud);
039        configureLeads(currentSerialPort, true, true);
040        setFlowControl(currentSerialPort, FlowControl.NONE);
041
042        // report status
043        reportPortStatus(log, portName);
044
045        opened = true;
046
047        return null; // indicates OK return
048    }
049
050    /**
051     * Set up all of the other objects to operate with a DCC++ device connected
052     * to this port.
053     */
054    @Override
055    public void configure() {
056        // connect to a packetizing traffic controller
057        DCCppTrafficController packets = new SerialDCCppPacketizer(new DCCppCommandStation());
058
059        String selectedStartupDelay = getOptionState(option1Name);
060        packets.startUpDelay = validStartupDelayValues[0];  // Default to the first option
061        for (int i=0; i < validStartupDelayValues.length; i++) {
062            if (selectedStartupDelay.equals(validStartupDelays[i])) {
063                packets.startUpDelay = validStartupDelayValues[i];
064            }
065        }
066
067        packets.connectPort(this);
068
069        // start operation
070        // packets.startThreads();
071        this.getSystemConnectionMemo().setDCCppTrafficController(packets);
072
073        new DCCppInitializationManager(this.getSystemConnectionMemo());
074    }
075
076    // base class methods for the XNetSerialPortController interface
077
078//     public BufferedReader getInputStreamBR() {
079//         if (!opened) {
080//             log.error("getInputStream called before load(), stream not available");
081//             return null;
082//         }
083//         return new BufferedReader(new InputStreamReader(getInputStream()));
084//     }
085
086    @Override
087    public boolean status() {
088        return opened;
089    }
090
091    /**
092     * {@inheritDoc}
093     */
094    @Override
095    public String[] validBaudRates() {
096        return Arrays.copyOf(validSpeeds, validSpeeds.length);
097    }
098
099    /**
100     * {@inheritDoc}
101     */
102    @Override
103    public int[] validBaudNumbers() {
104        return Arrays.copyOf(validSpeedValues, validSpeedValues.length);
105    }
106
107    protected String[] validSpeeds = new String[]{Bundle.getMessage("Baud115200")};
108    protected int[] validSpeedValues = new int[]{115200};
109
110    @Override
111    public int defaultBaudIndex() {
112        return 0;
113    }
114
115    // These two arrays works together so they must be consistent with eachother
116    protected String[] validStartupDelays = new String[]{"1.5 seconds", "5 seconds", "10 seconds", "20 seconds", "30 seconds"};
117    protected int[] validStartupDelayValues = new int[]{1500, 5000, 10000, 20000, 30000};
118
119    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DCCppAdapter.class);
120
121}