Updated .gitignore
[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         private SerialPort serialPort;
19         SerialState state;
20         private ConsoleMsg delegate; 
21         
22         public enum SerialState { Connecting, Connected, Disconnected };
23
24
25         public SerialWorker(ConsoleMsg d) {
26                 delegate=d;
27                 state = SerialState.Disconnected;
28         }
29         
30         public void connect(String d, String p)
31         {
32                 dev=d;
33                 pass=p;
34                 
35                 serialPort = new SerialPort(dev);               
36                 firePropertyChange("serialState", state, SerialState.Connecting );
37                 state = SerialState.Connecting;
38                 
39                 execute();
40         }
41         
42         public void disconnect()
43         {
44                 firePropertyChange("serialState", state, SerialState.Disconnected );
45
46                 
47                 if(serialPort != null && serialPort.isOpened() )
48                 {
49                         try {
50                                 serialPort.closePort();
51                         } catch (SerialPortException e) {
52                                 // TODO Auto-generated catch block
53                                 e.printStackTrace();
54                         }
55                 }
56         }
57
58         public String expectString(String expect, int timeOut)
59         {
60                 
61                 //Read from port, and if not found within 2 seconds, exit with null
62                 String in=new String();
63                 int msLeft=timeOut;
64                 while(true)
65                 {
66                         try {
67                                 if( serialPort.getInputBufferBytesCount() > 0)
68                                 {
69                                         in += serialPort.readString(serialPort.getInputBufferBytesCount());
70                                         
71                                         if( in.contains(expect))
72                                         {
73                                                 return(in);
74                                         }
75                                 } else {
76                                         Thread.sleep(10);
77                                         if(timeOut>0)
78                                         {
79                                                 msLeft -=10;
80                                                 if( msLeft < 1)
81                                                 {
82                                                         break;
83                                                 }
84                                         }
85                                 }
86                         } catch (Exception e)
87                         {
88                                 //I don't care
89                         }
90                 }
91                 
92                 return( null );
93         }
94         
95         
96         @Override
97         protected Void doInBackground() throws Exception {
98                 publish("Trying to connect to "+dev);
99                 /**
100                  * Connection strategy:
101                  * Open the port, wait for "The Final Key" followed by # on next line, (getLoginHeader)
102                  *      * If not coming, press q and try once more.
103                  * When [Granted] record [Keyboard: and query full list with Xk
104                  * 
105                  */
106                 
107                 int numAccounts=0;
108                 try {
109                         System.out.println("Port opened: " + serialPort.openPort());
110                         System.out.println("Params setted: " + serialPort.setParams(9600, 8, 1, 0));
111                         
112                         serialPort.addEventListener(this);
113                         String test = expectString("The Final Key", 1000);
114                         if( test != null )
115                         {
116                                 publish("Ready to log in, press button now.");
117                                 publish("Waiting for button press...");
118                         } else {
119                                 //Try logging out.
120                                 serialPort.writeByte( (byte)'q');
121                                 publish("State error, try again.");
122                                 disconnect();
123                                 return null;
124                         }
125                         
126                         if( expectString( "Pass:", 0 ) != null )
127                         {
128                                 publish("Logging in...");
129                         } else {
130                                 publish("Error: Did not get password prompt. Unplug and try again.");
131                                 disconnect();
132                                 return null;
133                         }
134
135                         serialPort.writeBytes(pass.getBytes());
136                         serialPort.writeByte( (byte)13 );
137                         pass = "";
138                         
139                         
140                         if( expectString( "[Granted]", 200 ) != null )
141                         {
142                                 publish("Access Granted.");
143                         } else {
144                                 publish("Error: Access Denied.");
145                                 disconnect();
146                                 return null;
147                         }
148
149                         publish("Getting account list...");
150                         serialPort.writeByte( (byte)'X'); //Machine commands with uppercase X
151                         expectString("[auto]", 200);
152                         serialPort.writeByte( (byte)'l'); //Full list 
153
154                         
155                         String accounts = new String();
156                         
157                         int timeOut = 10000;
158                         while(true)
159                         {
160                                 
161                                 if( serialPort.getInputBufferBytesCount() > 0 )
162                                 {
163                                         accounts += serialPort.readString();
164                                         String sub = accounts.substring( accounts.length()-3 );
165                                         if( sub.equals("\r\n>") )
166                                         {
167                                                 accounts = accounts.substring( 0, accounts.length()-3 );
168                                                 break;
169                                         }
170                                 } else {
171                                         Thread.sleep(10);
172                                         timeOut-=10;
173                                         if(timeOut < 1)
174                                         {
175                                                 publish("Error getting account list.");
176                                                 disconnect();
177                                                 return null;
178                                         }
179                                 }
180                         }
181                         
182                         //Trim first 3
183                         accounts = accounts.substring(3);
184
185                         String[] lines = accounts.split( "\r\n" );
186                         numAccounts=lines.length;
187                         for(String l:lines)
188                         {
189                                 String ac = l.substring(0,2);
190                                 String an = l.substring(2);
191                                 
192                                 //publish( "Account number: "+ac+" ["+an+"]");
193
194                                 Menu menu = new Menu(an+" ["+ac+"]");
195                                 MenuItem both = new MenuItem("User + Pass");
196                                 MenuItem usr = new MenuItem("User");
197                                 MenuItem psw = new MenuItem("Pass");
198                                 menu.add(both);
199                                 menu.add(usr);
200                                 menu.add(psw);
201
202                                 FireActionListener fal = new FireActionListener();
203                                 fal.action = "%";
204                                 fal.name = an;
205                                 fal.num = ac;
206                                 fal.port = serialPort;
207                                 both.addActionListener(fal);
208
209
210                                 fal = new FireActionListener();
211                                 fal.action = "p";
212                                 fal.name = an;
213                                 fal.num = ac;
214                                 fal.port = serialPort;
215                                 psw.addActionListener(fal);                     
216
217                                 fal = new FireActionListener();
218                                 fal.action = "u";
219                                 fal.name = an;
220                                 fal.num = ac;
221                                 fal.port = serialPort;
222                                 usr.addActionListener(fal);                     
223
224                                 delegate.getPopup().add(menu);
225                         }
226
227                 }
228                 catch (SerialPortException ex){
229                         System.out.println(ex);
230                 } catch (Exception e )
231                 {
232                         System.out.println("Other exception: "+e.getMessage() );
233                         e.printStackTrace();
234                 }
235
236                 if(numAccounts==1)
237                 {
238                         publish(numAccounts+" account.");
239                 } else {
240                         publish(numAccounts+" accounts ready.");
241                 }
242
243                 publish("Use the systray icon to trigger.");
244
245                 firePropertyChange("serialState", state, SerialState.Connected );
246                 state = SerialState.Connected;
247                 
248                 return null;
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         @Override
266         protected void process(List<String> msgs) {
267                 for(String s : msgs)
268                 {
269                         
270                         Display.getDefault().asyncExec( new MainWinMsg(delegate, s) );
271                 }
272         }
273
274         @Override
275         public void serialEvent(SerialPortEvent event) {
276                 
277                 if(event.isBREAK())
278                         System.out.println(">>BREAK);");
279                 if(event.isERR())
280                         System.out.println(">>Err");
281                 if(serialPort == null)
282                         System.out.println(">>Null");
283
284         }
285
286
287 }