00001 package edu.stanford.hci.r3.pen.streaming;
00002
00003 import java.io.IOException;
00004 import java.net.ServerSocket;
00005 import java.net.Socket;
00006 import java.util.ArrayList;
00007 import java.util.List;
00008
00009 import edu.stanford.hci.r3.config.Constants;
00010 import edu.stanford.hci.r3.pen.PenSample;
00011 import edu.stanford.hci.r3.pen.streaming.data.PenServerJavaObjectXMLSender;
00012 import edu.stanford.hci.r3.pen.streaming.data.PenServerPlainTextSender;
00013 import edu.stanford.hci.r3.pen.streaming.data.PenServerSender;
00014 import edu.stanford.hci.r3.pen.streaming.listeners.PenListener;
00015 import edu.stanford.hci.r3.util.DebugUtils;
00016 import edu.stanford.hci.r3.util.communications.COMPort;
00017 import edu.stanford.hci.r3.util.networking.ClientServerType;
00018
00028 public class PenServer implements PenListener {
00029
00033 private class ServerThread implements Runnable {
00034
00035 private void log(String msg) {
00036 DebugUtils.printlnWithStackOffset(msg, 1);
00037 }
00038
00039 public void run() {
00040 while (true) {
00041 Socket s = null;
00042
00043 if (exitFlag) {
00044 log("Closing Pen Server.");
00045 break;
00046 }
00047
00048 try {
00049 if (serverType == ClientServerType.PLAINTEXT) {
00050 log("Waiting for a plain text connection on port " + serverSocket.getLocalPort()
00051 + "...");
00052 } else {
00053 log("Waiting for a java connection on port " + serverSocket.getLocalPort() + "...");
00054 }
00055 s = serverSocket.accept();
00056 log("Got a connection on port " + serverSocket.getLocalPort() + "...");
00057 log("Client IP Addr is " + s.getRemoteSocketAddress());
00058 } catch (IOException ioe) {
00059 log("Error with server socket: " + ioe.getLocalizedMessage());
00060 }
00061 if (s != null) {
00062 try {
00063 if (serverType == ClientServerType.PLAINTEXT) {
00064 outputs.add(new PenServerPlainTextSender(s));
00065 } else {
00066 outputs.add(new PenServerJavaObjectXMLSender(s));
00067 }
00068 } catch (IOException ioe) {
00069 try {
00070 s.close();
00071 } catch (IOException ioe2) {
00072 log("Error with server socket: " + ioe2.getLocalizedMessage());
00073 }
00074 log("Error creating output: " + ioe.getLocalizedMessage());
00075 }
00076 }
00077
00078 }
00079 }
00080 }
00081
00085 public static final int DEFAULT_JAVA_PORT = Constants.Ports.PEN_SERVER_JAVA;
00086
00087 public static final int DEFAULT_PLAINTEXT_PORT = Constants.Ports.PEN_SERVER_PLAINTEXT;
00088
00089 public static final COMPort DEFAULT_SERIAL_PORT = COMPort.COM5;
00090
00091 private static PenServer javaPenServer;
00092
00093 private static PenServer textPenServer;
00094
00098 private static PenStreamingConnection penConnection;
00099
00103 public static boolean javaServerStarted() {
00104 return javaPenServer != null;
00105 }
00106
00110 private static void log(String msg) {
00111 DebugUtils.printlnWithStackOffset(msg, 1);
00112 }
00113
00117 public static void main(String[] args) {
00118
00119
00120 COMPort serialPort = DEFAULT_SERIAL_PORT;
00121 int tcpipPortJava = DEFAULT_JAVA_PORT;
00122 int tcpipPortPlainText = DEFAULT_PLAINTEXT_PORT;
00123
00124 if (args.length >= 1) {
00125 if (args[0].equals("?")) {
00126 DebugUtils.println("Usage: PenServer [Serial Port] "
00127 + "[TCP/IP Port for Java] [TCP/IP Port for Plain Text]");
00128 DebugUtils.println("Example: PenServer COM5 11025 11026");
00129 System.exit(0);
00130 } else {
00131 serialPort = COMPort.valueOf(args[0]);
00132 }
00133 }
00134
00135 if (args.length >= 2) {
00136 tcpipPortJava = Integer.parseInt(args[1]);
00137 }
00138 if (args.length >= 3) {
00139 tcpipPortPlainText = Integer.parseInt(args[2]);
00140 }
00141
00142 startBothServers(serialPort, tcpipPortJava, tcpipPortPlainText);
00143 }
00144
00151 public static void startBothServers(COMPort serialPortName, int tcpipPortJava, int tcpipPortPlainText) {
00152 startJavaServer(serialPortName, tcpipPortJava);
00153 startTextServer(serialPortName, tcpipPortPlainText);
00154 }
00155
00159 public static void startJavaServer() {
00160 startJavaServer(DEFAULT_SERIAL_PORT, DEFAULT_JAVA_PORT);
00161 }
00162
00168 public static void startJavaServer(COMPort serialPort) {
00169 startJavaServer(serialPort, DEFAULT_JAVA_PORT);
00170 }
00171
00178 public static void startJavaServer(COMPort serialPort, int tcpipPort) {
00179 try {
00180
00181 penConnection = PenStreamingConnection.getInstance(serialPort);
00182 if (penConnection == null) {
00183 DebugUtils.println("The PenServer could not connect to the local serial port.");
00184 return;
00185 }
00186
00187 final ServerSocket javaServer = new ServerSocket(tcpipPort);
00188 javaPenServer = new PenServer(javaServer, ClientServerType.JAVA);
00189 penConnection.addPenListener(javaPenServer);
00190 } catch (IOException ioe) {
00191 log("Error with server socket: " + ioe.getLocalizedMessage());
00192 }
00193 }
00194
00198 public static void startTextServer() {
00199 startTextServer(DEFAULT_SERIAL_PORT, DEFAULT_PLAINTEXT_PORT);
00200 }
00201
00208 public static void startTextServer(COMPort serialPort, int tcpipPort) {
00209 try {
00210 penConnection = PenStreamingConnection.getInstance(serialPort);
00211 final ServerSocket textServer = new ServerSocket(tcpipPort);
00212 textPenServer = new PenServer(textServer, ClientServerType.PLAINTEXT);
00213 penConnection.addPenListener(textPenServer);
00214 } catch (IOException ioe) {
00215 log("Error with server socket: " + ioe.getLocalizedMessage());
00216 }
00217 }
00218
00222 public static void stopServers() {
00223 if (javaPenServer != null) {
00224 javaPenServer.stopServer();
00225 javaPenServer = null;
00226 }
00227
00228 if (textPenServer != null) {
00229 textPenServer.stopServer();
00230 textPenServer = null;
00231 }
00232 }
00233
00237 public static boolean textServerStarted() {
00238 return textPenServer != null;
00239 }
00240
00241 private boolean exitFlag = false;
00242
00243 private List<PenServerSender> outputs;
00244
00248 private boolean penUp = true;
00249
00250 private ServerSocket serverSocket;
00251
00252 private ClientServerType serverType;
00253
00258 public PenServer(ServerSocket ss, ClientServerType type) {
00259 serverSocket = ss;
00260 serverType = type;
00261 outputs = new ArrayList<PenServerSender>();
00262
00263
00264 new Thread(new ServerThread()).start();
00265 }
00266
00270 public boolean isPenUp() {
00271 return penUp;
00272 }
00273
00281 public void penDown(PenSample s) {
00282 penUp = false;
00283 sample(s);
00284 }
00285
00290 public void penUp(PenSample s) {
00291 penUp = true;
00292
00293 sample(s);
00294 }
00295
00299 public void sample(PenSample sample) {
00300 final List<PenServerSender> toRemove = new ArrayList<PenServerSender>();
00301
00302 for (PenServerSender out : outputs) {
00303 try {
00304 out.sendSample(sample);
00305 } catch (IOException ioe) {
00306 log("Error sending sample, removing output " + ioe.getLocalizedMessage());
00307 toRemove.add(out);
00308 }
00309 }
00310
00311 for (PenServerSender penServerOutput : toRemove) {
00312 penServerOutput.destroy();
00313 outputs.remove(penServerOutput);
00314 }
00315 }
00316
00321 private void stopServer() {
00322 try {
00323 log("PenServer::" + serverType + " on port " + serverSocket.getLocalPort() + " is stopping...");
00324 exitFlag = true;
00325 serverSocket.close();
00326
00327 penConnection.exit();
00328 } catch (IOException e) {
00329 e.printStackTrace();
00330 }
00331 }
00332
00333 }