13307ecfcbd8c5bfff34b69d48ed4e59414fbeaf
[FinalKeyGui.git] / src / fkgui / SerialWorker.java
1 package fkgui;
2
3 import java.util.List;
4
5 import jssc.SerialPort;
6 import jssc.SerialPortEvent;
7 import jssc.SerialPortEventListener;
8 import jssc.SerialPortException;
9
10 import org.eclipse.swt.widgets.Display;
11
12
13 public class SerialWorker extends javax.swing.SwingWorker<Void, String> implements SerialPortEventListener {
14         public String dev;
15         public String pass;
16         public SerialPort serialPort;
17         SerialState state;
18         private ConsoleMsg delegate; 
19         
20         public enum SerialState { Connecting,Working, Connected, Disconnected };
21
22
23         public SerialWorker(ConsoleMsg d) {
24                 delegate=d;
25                 state = SerialState.Disconnected;
26                 FkManager.getInstance().setWorker(this);
27         }
28         
29         public void connect(String d, String p)
30         {
31                 dev=d;
32                 pass=p;
33                 
34                 serialPort = new SerialPort(dev);               
35
36                 state = SerialState.Connecting;
37                 postStateChange( state );
38                 FkManager.getInstance().listClear();
39                 execute();
40         }
41         
42         public void disconnect()
43         {
44                 if(serialPort != null && serialPort.isOpened() )
45                 {
46                         try {
47                                 serialPort.writeByte( (byte)'q'); //Machine commands with uppercase X
48                                 Thread.sleep(400);
49                                 serialPort.closePort();
50                         } catch (Exception e) {
51                                 // TODO Auto-generated catch block
52                                 e.printStackTrace();
53                         }
54                 }
55                 state = SerialState.Disconnected;
56                 postStateChange( SerialState.Disconnected);
57         }
58
59         public String expectString(String expect, int timeOut)
60         {
61                 
62                 //Read from port, and if not found within 2 seconds, exit with null
63                 String in=new String();
64                 int msLeft=timeOut;
65                 while(true)
66                 {
67                         try {
68                                 if( serialPort.getInputBufferBytesCount() > 0)
69                                 {
70                                         in += serialPort.readString(serialPort.getInputBufferBytesCount());
71                                         
72                                         if( in.contains(expect))
73                                         {
74                                                 return(in);
75                                         }
76                                 } else {
77                                         Thread.sleep(10);
78                                         if(timeOut>0)
79                                         {
80                                                 msLeft -=10;
81                                                 if( msLeft < 1)
82                                                 {
83                                                         break;
84                                                 }
85                                         }
86                                 }
87                         } catch (Exception e)
88                         {
89                                 //I don't care
90                         }
91                 }
92                 
93                 return( null );
94         }
95         
96         
97         @Override
98         protected Void doInBackground() throws Exception {
99                 publish(Messages.SerialWorker_0+dev);
100                 /**
101                  * Connection strategy:
102                  * Open the port, wait for "The Final Key" followed by # on next line, (getLoginHeader)
103                  *      * If not coming, press q and try once more.
104                  * When [Granted] record [Keyboard: and query full list with Xk
105                  * 
106                  */
107                 
108                 int numAccounts=0;
109                 try {
110                         System.out.println(Messages.SerialWorker_1 + serialPort.openPort());
111                         System.out.println(Messages.SerialWorker_2 + serialPort.setParams(9600, 8, 1, 0));
112
113                         int mask = SerialPort.MASK_BREAK + SerialPort.MASK_ERR + SerialPort.MASK_RLSD;
114                         serialPort.setEventsMask(mask);
115
116                         serialPort.addEventListener(this);
117                         String test = expectString("The Final Key", 1000); //$NON-NLS-1$
118                         if( test != null )
119                         {
120                                 publish(Messages.SerialWorker_4);
121                         } else {
122                                 //Try logging out.
123                                 serialPort.writeByte( (byte)'q');
124                                 publish(Messages.SerialWorker_5);
125                                 disconnect();
126                                 return null;
127                         }
128                         
129                         if( expectString( "Pass:", 0 ) != null ) //$NON-NLS-1$
130                         {
131                                 publish(Messages.SerialWorker_7);
132                                 postStateChange(SerialState.Working);
133                         } else {
134                                 publish(Messages.SerialWorker_8);
135                                 disconnect();
136                                 return null;
137                         }
138
139                         enterString(pass);
140
141                         serialPort.writeByte( (byte)13 );
142                         pass = ""; //$NON-NLS-1$
143                         
144                         /*String str = expectString( "[Keyboard: ", 200 );
145                         if( str != null )
146                         {
147                                 FkManager.getInstance().setCurrentLayout( str );
148                         } else {
149                                 publish("Did not get Keyboard layout.");
150                         }*/
151                         
152                         if( expectString( "[Granted]", 200 ) != null ) //$NON-NLS-1$
153                         {
154                                 publish(Messages.SerialWorker_11);
155                         } else {
156                                 publish(Messages.SerialWorker_12);
157                                 disconnect();
158                                 return null;
159                         }
160
161                         publish(Messages.SerialWorker_13);
162                         serialPort.writeByte( (byte)'X'); //Machine commands with uppercase X
163                         expectString("[auto]", 200); //$NON-NLS-1$
164                         serialPort.writeByte( (byte)'l'); //Full list 
165
166                         
167                         String accounts = new String();
168                         
169                         int timeOut = 10000;
170                         while(true)
171                         {
172                                 
173                                 if( serialPort.getInputBufferBytesCount() > 0 )
174                                 {
175                                         accounts += serialPort.readString();
176                                         String sub = accounts.substring( accounts.length()-3 );
177                                         if( sub.equals("\r\n>") ) //$NON-NLS-1$
178                                         {
179                                                 accounts = accounts.substring( 0, accounts.length()-3 );
180                                                 break;
181                                         }
182                                 } else {
183                                         Thread.sleep(10);
184                                         timeOut-=10;
185                                         if(timeOut < 1)
186                                         {
187                                                 publish(Messages.SerialWorker_16);
188                                                 disconnect();
189                                                 return null;
190                                         }
191                                 }
192                         }
193                         
194                         //Trim first 3
195                         accounts = accounts.substring(3);
196
197                         String[] lines = accounts.split( "\r\n" ); //$NON-NLS-1$
198                         numAccounts=lines.length;
199                         Boolean kbList=false;
200                         for(String l:lines)
201                         {
202                                 if( ! kbList )
203                                 {
204                                         if( l.compareTo("[KBL]") == 0 ) //$NON-NLS-1$
205                                         {
206                                                 kbList=true;
207                                         } else {
208                                                 String ac = l.substring(0,2);
209                                                 String an = l.substring(2);
210                                                 FkManager.getInstance().listAddAcc(ac, an);
211                                         }
212                                 } else {
213                                         //Next entries are supported keyboard layouts
214                                         publish(Messages.SerialWorker_3 + l);
215                                 }
216                         }
217
218                 }
219                 catch (Exception ex){
220                         publish("Error: Exception: "+ex.getMessage() ); //$NON-NLS-1$
221                         disconnect();
222                 }
223
224                 if( state != SerialState.Disconnected )
225                 {
226                         if(numAccounts==1)
227                         {
228                                 publish(numAccounts+" account."); //$NON-NLS-1$
229                         } else {
230                                 publish(numAccounts+" accounts ready."); //$NON-NLS-1$
231                         }
232         
233                         publish(Messages.SerialWorker_23);
234
235                         state = SerialState.Connected;
236                         postStateChange( state);
237                 }
238                 
239                 return null;
240         }
241
242
243         private void enterString(String str) throws SerialPortException, InterruptedException {
244                 for(int i=0; i < str.length(); i++)
245                 {
246                         serialPort.writeByte( str.getBytes()[i] );
247                         Thread.sleep(20);
248                 }
249         }
250
251
252         private class MainWinMsg implements Runnable {
253                 private String msg;
254                 private ConsoleMsg delegate;
255                 MainWinMsg(ConsoleMsg d, String m)
256                 {
257                         delegate=d;
258                         msg=m;
259                 }
260                 public void run() {
261                         delegate.log(msg);
262                 }
263         }
264         
265         private class MainWinSerialChange implements Runnable  {
266                 private ConsoleMsg delegate;
267                 private SerialState state;
268                 private MainWinSerialChange(ConsoleMsg d, SerialState s )
269                 {
270                         delegate=d;
271                         state=s;
272                 }
273                 @Override
274                 public void run() {
275                         delegate.serialEvent(state);
276                 }
277         }
278
279         private void postStateChange(SerialState state)
280         {
281                 Display.getDefault().asyncExec( new MainWinSerialChange(delegate, state) );
282         }
283
284         @Override
285         protected void process(List<String> msgs) {
286                 for(String s : msgs)
287                 {
288                         
289                         Display.getDefault().asyncExec( new MainWinMsg(delegate, s) );
290                 }
291         }
292
293         @Override
294         public void serialEvent(SerialPortEvent event) {
295                 
296                 System.out.println("Event!" + event.getEventType() ); //$NON-NLS-1$
297
298                 if(event.isBREAK())
299                 {
300                         if(state!=SerialState.Disconnected)
301                         {
302                                 disconnect();
303                                 System.out.println(">>Break);"); //$NON-NLS-1$
304                         }
305                 }
306                 if(event.isERR())
307                 {
308                         if(state!=SerialState.Disconnected)
309                         {
310                                 disconnect();
311                                 System.out.println(">>Error"); //$NON-NLS-1$
312                         }
313                 }
314                 if(serialPort == null)
315                         System.out.println(">>Null"); //$NON-NLS-1$
316
317         }
318
319
320 }