move flow control from Client to Server
[fleet.git] / src / edu / berkeley / fleet / fpga / Server.java
1 package edu.berkeley.fleet.fpga;
2
3 import gnu.io.*;
4 import java.io.*;
5 import java.net.*;
6 import java.util.*;
7 import java.util.concurrent.Semaphore;
8
9 // FIXME: accept connections, but stall, during programming
10 public class Server {
11     static boolean sign = false;
12
13     static long jarFileTime = 0;
14     static long bitFileTime = 0;
15     static {
16         try {
17             jarFileTime = new File("fleet.jar").lastModified();
18             bitFileTime = new File("build/fpga/main.bit").lastModified();
19         } catch (Exception e) { throw new RuntimeException(e); }
20     }
21
22     public static ServerSocket ss;
23     public static void main(String[] args) throws Exception {
24         System.err.println("programming...");
25         Process proc = Runtime.getRuntime().exec(new String[] {
26                 "misc/program.sh",
27                 "build/fpga/main.bit"
28             });
29         BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
30         String str = null;
31         while((str = br.readLine()) != null) {
32             System.err.println("  " + str);
33         }
34         int ret = proc.waitFor();
35         if (ret != 0) {
36             System.err.println("programming error: " + ret);
37             return;
38         }
39         System.err.println("done programming.");
40         new Thread() {
41             public void run() {
42                 try {
43                     while(true) {
44                         Thread.sleep(500);
45                         if (jarFileTime != new File("fleet.jar").lastModified()) {
46                             System.err.println("jarfile modified; exiting...");
47                             System.exit(0);
48                         }
49                         if (bitFileTime != new File("build/fpga/main.bit").lastModified()) {
50                             System.err.println("bitfile modified; exiting...");
51                             System.exit(0);
52                         }
53                     }
54                 } catch (Exception e) { throw new RuntimeException(e); }
55             }
56         }.start();
57         ss = new ServerSocket(3133);
58         while(true) {
59             try {
60                 Socket s = ss.accept();
61                 System.out.println("accept!");
62                 new Handler(s).start();
63             } catch (Exception e) {
64                 e.printStackTrace();
65             }
66         }
67     }
68
69     public static String pass_string = "password=security_is_for_wimps ";
70     static class Handler extends Thread {
71         private Socket socket;
72         boolean closed = false;
73         private SerialPort sp;
74         public Handler(Socket s) { this.socket = s; this.sp = sp; }
75         public void run() {
76             System.err.println("waiting for Server.class lock...");
77             synchronized(Server.class) {
78                 System.err.println("   (got it)");
79                 try {
80                     this.sp = new RXTXPort("/dev/ttyS0");
81                     sp.setInputBufferSize(0);
82                     sp.setOutputBufferSize(0);
83                     sp.setSerialPortParams(38400, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
84                     //sp.setFlowControlMode(sp.FLOWCONTROL_RTSCTS_IN | sp.FLOWCONTROL_RTSCTS_OUT);
85                     sp.setFlowControlMode(0);
86                     try {
87                         _run();
88                     } finally {
89                         sp.close();
90                     }
91                 } catch (Exception e) { throw new RuntimeException(e); }
92             }
93         }
94         public void _run() {
95             try {
96                 final InputStream is = new BufferedInputStream(socket.getInputStream());
97                 byte[] buf = new byte[1024];
98                 StringBuffer sb = new StringBuffer();
99                 while(true) {
100                     int i = is.read();
101                     if (i==-1) return;
102                     if (((char)i)=='\n') break;
103                     sb.append((char)i);
104                 }
105                 System.err.println("login string: " + sb.toString());
106                 if (!sb.toString().startsWith(pass_string)) return;
107                 final OutputStream os = new BufferedOutputStream(socket.getOutputStream());
108
109                 final OutputStream fos = sp.getOutputStream();
110                 final InputStream fis = new BufferedInputStream(sp.getInputStream());
111
112                 final Semaphore sem = new Semaphore(15);
113
114                 System.err.println("sending instructions...");
115                 new Thread() {
116                     public void run() {
117                         try {
118                             while(true) {
119                                 int r = is.read();
120                                 if (r == -1) break;
121                                 synchronized(fos) {
122                                     fos.write(r);
123                                 }
124                             }
125                             fos.flush();
126                         } catch (Exception e) { throw new RuntimeException(e);
127                         } finally {
128                             System.err.println("closing...");
129                             closed = true;
130                             try { fos.close(); } catch (Throwable t) { t.printStackTrace(); }
131                         }
132                     }
133                 }.start();
134
135                 System.err.println("reading back...");
136                 while(true) {
137                     long result = 0;
138                     int val = 0;
139                     boolean hit=false;
140                     for(int i=0; i<6; i++) {
141                         int k = 0;
142                         while(!closed && fis.available()==0) {
143                             if (closed) return;
144                             k++;
145                             if (k >= 100) {
146                                 System.err.println("sleep");
147                                 k = 0;
148                             }
149                             if (k==10) os.flush();
150                             Thread.sleep(10);
151                         }
152                         if (closed) { os.flush(); return; }
153                         val = fis.read();
154                         if (val==-1) break;
155                         if ((val & (1<<6)) == 0) {
156                             synchronized(fos) {
157                                 fos.write( (1<<6) | 1);
158                             }
159                         }
160                         System.err.println("byte: 0x"+Integer.toString(val & 0xff, 16));
161                         os.write((byte)val);
162                         result |= ((long)val) << (i * 8);
163                     }
164                     if (val==-1) break;
165                     System.err.print(result);
166                     System.err.print(" 0x");
167                     System.err.print(Long.toString(result, 16));
168                     System.err.println();
169                 }
170                 os.flush();
171                 System.err.println("done.");
172
173             } catch (Exception e) { throw new RuntimeException(e);
174             } finally {
175                 try {
176                     System.err.println("closing...");
177                     /*
178                     fis.close();
179                     if (fis != null) fis.close();
180                     */
181                 } catch (Throwable t) { t.printStackTrace(); }
182             }
183         }
184     }
185
186 }