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