001package jmri.jmrix.loconet.hexfile;
002
003import jmri.DccLocoAddress;
004import jmri.DccThrottle;
005import jmri.GlobalProgrammerManager;
006import jmri.LocoAddress;
007import jmri.jmrix.debugthrottle.DebugThrottleManager;
008import jmri.jmrix.loconet.LnCommandStationType;
009import jmri.jmrix.loconet.LnPacketizer;
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013/**
014 * copied from HexFileFrame, then all ui-related elements removed.
015 * ConnectionConfigXml.load() calls HexFileServer instead of HexFileFrame if
016 * jmri is running in headless mode.
017 *
018 * @author Steve Todd Copyright 2012
019 */
020public class HexFileServer {
021        
022    private int connectedAddresses = 0;
023
024    // member declarations
025    // to find and remember the log file
026    // final javax.swing.JFileChooser inputFileChooser =
027    // jmri.jmrit.XmlFile.userFileChooser("Hex files", "hex");
028    public HexFileServer() {
029    }
030
031    boolean connected = false;
032
033    public void dispose() {
034    }
035
036    LnPacketizer packets = null;
037
038    public void configure() {
039        if (port == null) {
040            log.error("initComponents called before adapter has been set");
041            return;
042        }
043        // connect to a packetizing LnTrafficController
044        packets = new LnPacketizer(port.getSystemConnectionMemo());
045        packets.connectPort(port);
046        connected = true;
047
048        // set tc in memo
049        port.getSystemConnectionMemo().setLnTrafficController(packets);
050
051        // do the common manager config
052        port.getSystemConnectionMemo().configureCommandStation(LnCommandStationType.COMMAND_STATION_DCS100, // full featured by default
053                false, false, false);
054        port.getSystemConnectionMemo().configureManagers();
055
056        // Install a debug programmer, replacing the existing LocoNet one
057        port.getSystemConnectionMemo().setProgrammerManager(
058                new jmri.progdebugger.DebugProgrammerManager(port.getSystemConnectionMemo()));
059        if (port.getSystemConnectionMemo().getProgrammerManager().isAddressedModePossible()) {
060            jmri.InstanceManager.store(port.getSystemConnectionMemo().getProgrammerManager(), jmri.AddressedProgrammerManager.class);
061        }
062        if (port.getSystemConnectionMemo().getProgrammerManager().isGlobalProgrammerAvailable()) {
063            jmri.InstanceManager.store(port.getSystemConnectionMemo().getProgrammerManager(), GlobalProgrammerManager.class);
064        }
065
066        // Install a debug throttle manager and override 
067        DebugThrottleManager tm = new DebugThrottleManager(port.getSystemConnectionMemo() ) {
068            /**
069             * Only address 128 and above can be a long address
070             */
071            @Override
072            public boolean canBeLongAddress(int address) {
073                return (address >= 128);
074            }
075
076            @Override
077            public void requestThrottleSetup(LocoAddress a, boolean control) {
078                if (!(a instanceof DccLocoAddress)) {
079                    log.error("{} is not a DccLocoAddress",a);
080                    failedThrottleRequest(a, "LocoAddress " + a + " is not a DccLocoAddress");
081                    return;
082                }
083                DccLocoAddress address = (DccLocoAddress) a;
084                //create some testing situations
085                if (connectedAddresses >= 5) {
086                    log.warn("SLOT MAX of 5 reached, Current={}", connectedAddresses);
087                    failedThrottleRequest(address, "SLOT MAX of 5 reached");
088                    return;
089                }
090                // otherwise, continue with setup
091                super.requestThrottleSetup(a, control);
092                connectedAddresses++;
093            }
094
095            @Override
096            public boolean disposeThrottle(DccThrottle t, jmri.ThrottleListener l) {
097                if (super.disposeThrottle(t, l)) {
098                    connectedAddresses--;
099                    return true;
100                }
101                return false;
102            }    
103        };
104
105        port.getSystemConnectionMemo().setThrottleManager(tm);
106
107        jmri.InstanceManager.setThrottleManager(
108                port.getSystemConnectionMemo().getThrottleManager());
109
110        // start operation of packetizer
111        packets.startThreads();
112        sourceThread = new Thread(port, "LocoNet HexFileServer");
113        sourceThread.start();
114    }
115
116    private Thread sourceThread;
117    //private Thread sinkThread;
118
119    public void setAdapter(LnHexFilePort adapter) {
120        port = adapter;
121    }
122
123    public LnHexFilePort getAdapter() {
124        return port;
125    }
126    private LnHexFilePort port = null;
127
128    private final static Logger log = LoggerFactory.getLogger(HexFileServer.class);
129
130}