001package jmri.jmrix.nce.networkdriver;
002
003import jmri.jmrix.nce.NceCmdStationMemory;
004import jmri.jmrix.nce.NceNetworkPortController;
005import jmri.jmrix.nce.NceSystemConnectionMemo;
006import jmri.jmrix.nce.NceTrafficController;
007
008/**
009 * Implements SerialPortAdapter for the NCE system network connection.
010 * <p>
011 * This connects an NCE command station via a telnet connection. Normally
012 * controlled by the NetworkDriverFrame class.
013 *
014 * @author Bob Jacobsen Copyright (C) 2001, 2002, 2003
015 * @author Ken Cameron Copyright (C) 2023
016 */
017public class NetworkDriverAdapter extends NceNetworkPortController {
018
019    public NetworkDriverAdapter() {
020        super(new NceSystemConnectionMemo());
021        option2Name = "Eprom";
022        // the default is 2006 or later
023        options.put(option2Name, new Option("Command Station EPROM", new String[]{"2006 or later", "2004 or earlier"}));
024        setManufacturer(jmri.jmrix.nce.NceConnectionTypeList.NCE);
025        // Auto-reconnect: same fix applied to CMRI's network driver -- the
026        // generic reconnect framework in AbstractPortController (exponential
027        // backoff, reconnectMaxAttempts/reconnectMaxInterval loaded from the
028        // saved connection XML) is already triggered automatically by
029        // AbstractMRTrafficController.receiveLoop() whenever the read loop
030        // exits abnormally, but it no-ops unless allowConnectionRecovery is
031        // explicitly turned on -- which NCE's network driver never did.
032        // See resetupConnection() below for the other half of the fix.
033        allowConnectionRecovery = true;
034    }
035
036    /**
037     * set up all of the other objects to operate with an NCE command station
038     * connected to this port
039     */
040    @Override
041    public void configure() {
042        NceTrafficController tc = new NceTrafficController();
043        this.getSystemConnectionMemo().setNceTrafficController(tc);
044        tc.setAdapterMemo(this.getSystemConnectionMemo());
045
046        // set the command options, Note that the NetworkDriver uses
047        // the second option for EPROM revision
048        if (getOptionState(option2Name).equals(getOptionChoices(option2Name)[0])) {
049            // setting binary mode
050            this.getSystemConnectionMemo().configureCommandStation(NceTrafficController.OPTION_2006);
051            this.getSystemConnectionMemo().setNceCmdGroups(~NceTrafficController.CMDS_USB);
052        } else {
053            this.getSystemConnectionMemo().configureCommandStation(NceTrafficController.OPTION_2004);
054            this.getSystemConnectionMemo().setNceCmdGroups(~NceTrafficController.CMDS_USB);
055        }
056
057        tc.csm = new NceCmdStationMemory();
058        tc.connectPort(this);
059
060        this.getSystemConnectionMemo().configureManagers();
061    }
062
063    /**
064     * Called once a reconnect attempt succeeds. The traffic controller's
065     * transmit/receive threads were torn down when the connection was lost
066     * (AbstractMRTrafficController.recovery() calls disconnectPort() before
067     * attempting reconnection), so they need to be started again against the
068     * fresh socket streams -- connectPort() does both, the same call
069     * configure() made for the original connection.
070     */
071    @Override
072    protected void resetupConnection() {
073        getSystemConnectionMemo().getNceTrafficController().connectPort(this);
074    }
075
076}