001package jmri.jmrix.loconet;
002
003import org.slf4j.Logger;
004import org.slf4j.LoggerFactory;
005
006/**
007 * Base for classes representing a LocoNet communications port.
008 *
009 * @author Bob Jacobsen Copyright (C) 2001, 2002
010 */
011public abstract class LnPortController extends jmri.jmrix.AbstractSerialPortController {
012    // base class. Implementations will provide InputStream and OutputStream
013    // objects to LnTrafficController classes, who in turn will deal in messages.
014
015    protected LnPortController(LocoNetSystemConnectionMemo connectionMemo) {
016        super(connectionMemo);
017        setManufacturer(LnConnectionTypeList.DIGITRAX);
018    }
019
020    /**
021     * Check that this object is ready to operate. This is a question of
022     * configuration, not transient hardware status.
023     */
024    @Override
025    public abstract boolean status();
026
027    /**
028     * Can the port accept additional characters? This might go false for short
029     * intervals, but it might also stick off if something goes wrong.
030     * <p>
031     * Provide a default implementation for the MS100, etc.
032     *
033     * @return _always_ true, as we rely on the queueing in the port itself
034     */
035    public boolean okToSend() {
036        return true;
037    }
038
039    protected LnCommandStationType commandStationType = null;
040
041    protected boolean mTurnoutNoRetry = false;
042    protected boolean mTurnoutExtraSpace = false;
043    protected boolean mInterrogateAtStart = true;
044    protected boolean mTranspondingAvailable = false;
045
046    protected boolean mLoconetProtocolAutoDetect = true;
047
048    protected LnCommandStationType[] commandStationTypes = {
049        LnCommandStationType.COMMAND_STATION_DCS100,
050        LnCommandStationType.COMMAND_STATION_DCS240,
051        LnCommandStationType.COMMAND_STATION_DCS240PLUS,
052        LnCommandStationType.COMMAND_STATION_DCS210,
053        LnCommandStationType.COMMAND_STATION_DCS210PLUS,
054        LnCommandStationType.COMMAND_STATION_DCS200,
055        LnCommandStationType.COMMAND_STATION_DCS050,
056        LnCommandStationType.COMMAND_STATION_DCS051,
057        LnCommandStationType.COMMAND_STATION_DCS052,
058        LnCommandStationType.COMMAND_STATION_DB150,
059        LnCommandStationType.COMMAND_STATION_IBX_TYPE_1,
060        LnCommandStationType.COMMAND_STATION_IBX_TYPE_2,
061        LnCommandStationType.COMMAND_STATION_LBPS,
062        LnCommandStationType.COMMAND_STATION_MM};
063
064    protected String[] commandStationNames;
065
066    {
067        commandStationNames = new String[commandStationTypes.length];
068        int i = 0;
069        for (LnCommandStationType type : commandStationTypes) {
070            commandStationNames[i++] = type.getName();
071        }
072    }
073
074    // There are also "PR3 standalone programmer" and "Stand-alone LocoNet" in pr3/PR3Adapter
075    // and "PR2 standalone programmer" in pr2/Pr2Adapter
076    /**
077     * Set config info from a name, which needs to be one of the valid ones.
078     * @param name the name of the command station type
079     */
080    public void setCommandStationType(String name) {
081        setCommandStationType(LnCommandStationType.getByName(name));
082    }
083
084    /**
085     * Set config info from the command station type enum.
086     * @param value the LnCommandStationType
087     */
088    public void setCommandStationType(LnCommandStationType value) {
089        if (value == null) {
090            return;  // can happen while switching protocols
091        }
092        log.debug("setCommandStationType: {}", value); // NOI18N
093        commandStationType = value;
094    }
095
096    public void setTurnoutHandling(String value) {
097        if (value.equals("One Only") || value.equals(Bundle.getMessage("HandleOneOnly"))
098                || value.equals("Both") || value.equals(Bundle.getMessage("HandleBoth"))) {
099            mTurnoutNoRetry = true;
100        }
101        log.debug("turnout no retry: {}", mTurnoutNoRetry); // NOI18N
102        if (value.equals("Spread") || value.equals(Bundle.getMessage("HandleSpread"))
103                || value.equals("Both") || value.equals(Bundle.getMessage("HandleBoth"))) {
104            mTurnoutExtraSpace = true;
105        }
106        log.debug("turnout extra space: {}", mTurnoutExtraSpace); // NOI18N
107    }
108
109    public void setTranspondingAvailable(String value) {
110        // default (most common state) is off, so just check for Yes
111        mTranspondingAvailable = (value.equals("Yes") || value.equals(Bundle.getMessage("ButtonYes")));
112        log.debug("transponding available: {}", mTranspondingAvailable); // NOI18N
113    }
114
115    public void setLoconetProtocolAutoDetect(String value) {
116        // default (most common state) is off, so just check for Yes
117        mLoconetProtocolAutoDetect = (value.equals("Yes") || value.equals(Bundle.getMessage("LoconetProtocolAutoDetect")));
118        log.debug("Loconet XPSlots: {}", mLoconetProtocolAutoDetect); // NOI18N
119    }
120    
121    public void setInterrogateOnStart(String value) {
122        // default (most common state) is on, so just check for No
123        mInterrogateAtStart = !(value.equals("No") || value.equals(Bundle.getMessage("ButtonNo")));
124        log.debug("tInterrogate on Start: {}", mInterrogateAtStart); // NOI18N
125    }
126
127    @Override
128    public LocoNetSystemConnectionMemo getSystemConnectionMemo() {
129        return (LocoNetSystemConnectionMemo) super.getSystemConnectionMemo();
130    }
131
132    private final static Logger log = LoggerFactory.getLogger(LnPortController.class);
133
134}