001package jmri.jmris.simpleserver;
002
003import java.io.DataInputStream;
004import java.io.DataOutputStream;
005import java.io.IOException;
006import java.io.InputStreamReader;
007import java.nio.charset.StandardCharsets;
008import java.util.NoSuchElementException;
009import java.util.ResourceBundle;
010import java.util.Scanner;
011import jmri.InstanceManager;
012import jmri.JmriException;
013import jmri.jmris.JmriServer;
014import jmri.util.node.NodeIdentity;
015import jmri.web.server.WebServerPreferences;
016import org.slf4j.Logger;
017import org.slf4j.LoggerFactory;
018
019/**
020 * This is an implementation of a simple server for JMRI. There is currently no
021 * handshaking in this server. You may just start sending commands.
022 *
023 * @author Paul Bender Copyright (C) 2010
024 *
025 */
026public class SimpleServer extends JmriServer {
027
028    private static final String NOT_SUPPORTED = "not supported\n";
029    static ResourceBundle rb = ResourceBundle.getBundle("jmri.jmris.simpleserver.SimpleServerBundle");
030
031    // Create a new server using the default port
032    public SimpleServer() {
033        this(Integer.parseInt(rb.getString("SimpleServerPort")));
034    }
035
036    public SimpleServer(int port) {
037        super(port);
038        InstanceManager.setDefault(SimpleServer.class,SimpleServer.this);
039        log.info("JMRI SimpleServer started on port {}",port);
040    }
041
042    @Override
043    protected void advertise() {
044        this.advertise("_jmri-simple._tcp.local.");
045    }
046
047    // Handle communication to a client through inStream and outStream
048    @Override
049    public void handleClient(DataInputStream inStream, DataOutputStream outStream) throws IOException {
050        // Listen for commands from the client until the connection closes
051        try (Scanner inputScanner = new Scanner(new InputStreamReader(inStream, StandardCharsets.UTF_8))) {
052            // Listen for commands from the client until the connection closes
053            String cmd;
054            
055            // interface components
056            SimplePowerServer powerServer = new SimplePowerServer(inStream, outStream);
057            SimpleTurnoutServer turnoutServer = new SimpleTurnoutServer(inStream, outStream);
058            SimpleLightServer lightServer = new SimpleLightServer(inStream, outStream);
059            SimpleSensorServer sensorServer = new SimpleSensorServer(inStream, outStream);
060            SimpleSignalHeadServer signalHeadServer = new SimpleSignalHeadServer(inStream, outStream);
061            SimpleReporterServer reporterServer = new SimpleReporterServer(inStream, outStream);
062            SimpleOperationsServer operationsServer = new SimpleOperationsServer(inStream, outStream);
063            
064            // Start by sending a welcome message
065            outStream.writeBytes("JMRI " + jmri.Version.name() + " \n");
066            outStream.writeBytes("RAILROAD " + InstanceManager.getDefault(WebServerPreferences.class).getRailroadName() + " \n");
067            outStream.writeBytes("NODE " + NodeIdentity.networkIdentity() + " \n");
068            
069            while (true) {
070                inputScanner.skip("[\r\n]*");// skip any stray end of line characters.
071                // Read the command from the client
072                try {
073                    cmd = inputScanner.nextLine();
074                } catch (NoSuchElementException nse) {
075                    // we get an nse when we are finished with this client
076                    // so break out of the loop.
077                    break;
078                }
079                
080                log.debug("Received from client: {}",cmd);
081                if (cmd.startsWith("POWER")) {
082                    try {
083                        powerServer.parseStatus(cmd);
084                        powerServer.sendStatus(InstanceManager.getDefault(jmri.PowerManager.class).getPower());
085                    } catch (JmriException je) {
086                        outStream.writeBytes(NOT_SUPPORTED);
087                    }
088                } else if (cmd.startsWith("TURNOUT")) {
089                    try {
090                        turnoutServer.parseStatus(cmd);
091                    } catch (JmriException je) {
092                        outStream.writeBytes(NOT_SUPPORTED);
093                    }
094                } else if (cmd.startsWith("LIGHT")) {
095                    try {
096                        lightServer.parseStatus(cmd);
097                    } catch (JmriException je) {
098                        outStream.writeBytes(NOT_SUPPORTED);
099                    }
100                } else if (cmd.startsWith("SENSOR")) {
101                    try {
102                        sensorServer.parseStatus(cmd);
103                    } catch (JmriException je) {
104                        outStream.writeBytes(NOT_SUPPORTED);
105                    }
106                } else if (cmd.startsWith("SIGNALHEAD")) {
107                    try {
108                        signalHeadServer.parseStatus(cmd);
109                    } catch (JmriException je) {
110                        outStream.writeBytes(NOT_SUPPORTED);
111                    }
112                } else if (cmd.startsWith("REPORTER")) {
113                    try {
114                        reporterServer.parseStatus(cmd);
115                    } catch (JmriException je) {
116                        outStream.writeBytes(NOT_SUPPORTED);
117                    }
118                } else if (cmd.startsWith(SimpleOperationsServer.OPERATIONS)) {
119                    try {
120                        operationsServer.parseStatus(cmd);
121                    } catch (JmriException je) {
122                        outStream.writeBytes(NOT_SUPPORTED);
123                    }
124                } else {
125                    outStream.writeBytes("Unknown Command " + cmd + "\n");
126                }
127            }
128        }
129    }
130    private static final Logger log = LoggerFactory.getLogger(SimpleServer.class);
131}