001package jmri.jmrix.marklin.networkdriver;
002
003import java.io.DataInputStream;
004import java.io.DataOutputStream;
005import java.net.DatagramSocket;
006import jmri.jmrix.ConnectionStatus;
007import jmri.jmrix.marklin.MarklinPortController;
008import jmri.jmrix.marklin.MarklinSystemConnectionMemo;
009import jmri.jmrix.marklin.MarklinTrafficController;
010import jmri.util.com.rbnb.UDPInputStream;
011import jmri.util.com.rbnb.UDPOutputStream;
012import org.slf4j.Logger;
013import org.slf4j.LoggerFactory;
014
015/**
016 * Implements NetworkPortAdapter for the Marklin system network connection.
017 * <p>
018 * This connects a Marklin command station via a UDP connection. Normally
019 * controlled by the NetworkDriverFrame class.
020 *
021 * @author Bob Jacobsen Copyright (C) 2001, 2002, 2003, 2008
022 * @author Kevin Dickerson Copyright (C) 2012
023 */
024public class NetworkDriverAdapter extends MarklinPortController {
025
026    protected DatagramSocket datagramSocketConn = null;
027
028    public NetworkDriverAdapter() {
029        super(new MarklinSystemConnectionMemo());
030        allowConnectionRecovery = true;
031        manufacturerName = jmri.jmrix.marklin.MarklinConnectionTypeList.MARKLIN;
032        m_port = 15731;
033    }
034
035    @Override //ports are fixed and not user set
036    public void setPort(int p) {
037    }
038
039    @Override //ports are fixed and not user set
040    public void setPort(String p) {
041    }
042
043    @Override
044    public void connect() {
045        opened = false;
046
047        if (m_HostName == null) {
048            log.error("No host name or port set :{}:{}", m_HostName, m_port);
049            return;
050        }
051        try {
052            opened = true;
053        } catch (Exception e) {
054            log.error("a error opening network connection", e);
055            if (m_port != 0) {
056                ConnectionStatus.instance().setConnectionState(
057                        null, m_HostName + ":" + m_port, ConnectionStatus.CONNECTION_DOWN);
058            } else {
059                ConnectionStatus.instance().setConnectionState(
060                        null, m_HostName, ConnectionStatus.CONNECTION_DOWN);
061            }
062            throw (e);
063        }
064        if (opened && m_port != 0) {
065            ConnectionStatus.instance().setConnectionState(
066                    null, m_HostName + ":" + m_port, ConnectionStatus.CONNECTION_UP);
067        } else if (opened) {
068            ConnectionStatus.instance().setConnectionState(
069                    null, m_HostName, ConnectionStatus.CONNECTION_UP);
070        }
071    }
072
073    @Override
074    public DataInputStream getInputStream() {
075        if (!opened) {
076            log.error("getInputStream called before load(), stream not available");
077            if (m_port != 0) {
078                ConnectionStatus.instance().setConnectionState(
079                        null, m_HostName + ":" + m_port, ConnectionStatus.CONNECTION_DOWN);
080            } else {
081                ConnectionStatus.instance().setConnectionState(
082                        null, m_HostName, ConnectionStatus.CONNECTION_DOWN);
083            }
084        }
085        try {
086            return new DataInputStream(new UDPInputStream(null, 15730));
087        } catch (java.io.IOException ex1) {
088            log.error("an Exception getting input stream", ex1);
089            return null;
090        }
091    }
092
093    @Override
094    public DataOutputStream getOutputStream() {
095        if (!opened) {
096            log.error("getOutputStream called before load(), stream not available");
097        }
098        try {
099            return new DataOutputStream(new UDPOutputStream(m_HostName, 15731));
100        } catch (java.io.IOException e) {
101            log.error("getOutputStream exception", e);
102            if (m_port != 0) {
103                ConnectionStatus.instance().setConnectionState(
104                        null, m_HostName + ":" + m_port, ConnectionStatus.CONNECTION_DOWN);
105            } else {
106                ConnectionStatus.instance().setConnectionState(
107                        null, m_HostName, ConnectionStatus.CONNECTION_DOWN);
108            }
109        }
110        return null;
111    }
112
113    /**
114     * Set up all of the other objects to operate with a Marklin command station
115     * connected to this port.
116     */
117    @Override
118    public void configure() {
119        // connect to the traffic controller
120        MarklinTrafficController control = new MarklinTrafficController();
121        control.connectPort(this);
122        control.setAdapterMemo(this.getSystemConnectionMemo());
123        this.getSystemConnectionMemo().setMarklinTrafficController(control);
124        this.getSystemConnectionMemo().configureManagers();
125    }
126
127    @Override
128    public boolean status() {
129        return opened;
130    }
131
132    private final static Logger log = LoggerFactory.getLogger(NetworkDriverAdapter.class);
133
134}