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