cda22a7a1f2f029e2e86ee2a1397937047d53500
[FinalKeyGui.git] / src / fkgui / FkManager.java
1 package fkgui;
2
3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
5 import java.util.Collections;
6 import java.util.Comparator;
7 import java.util.Vector;
8
9 import jssc.SerialPort;
10
11 import org.eclipse.swt.widgets.Display;
12
13 import fkgui.FkActionEventListener.FkActionEvent;
14 import fkgui.FkActionEventListener.FkActionEventType;
15
16 public class FkManager implements ActionListener {
17         private static FkManager instance = null;
18         private SerialWorker com = null;
19         static final char ENTER_KEY = (char)13;
20         static final char PAUSE_CODE = (char)23; 
21         static final char SPACE_KEY = (char)32;
22         private Comparator<Account> sortMethod = null;
23         
24         public class Account
25         {
26                 public String name;
27                 public String num;
28                 
29                 public Account( String acNum, String acName )
30                 {
31                         name = acName;
32                         num = acNum;
33                 }
34                 
35                 public String toString()
36                 {
37                         return(name);
38                 }
39         }
40                 
41         private Vector<Account> list;
42         
43         protected FkManager()
44         {
45                 list = new Vector<Account>(256);
46         }
47         
48         public static FkManager getInstance()
49         {
50                 if( instance == null )
51                 {
52                         instance = new FkManager();
53                 }
54
55                 return( instance );
56         }
57         
58         public void setWorker( SerialWorker sw )
59         {
60                 com = sw;
61         }
62         
63
64         private class FkActionEventMsg implements Runnable  {
65                 private FkActionEventListener delegate;
66                 private FkActionEvent event;
67
68                 private FkActionEventMsg(FkActionEventListener d, FkActionEventType t, String data, Account acc, char act )
69                 {
70                         delegate=d;
71                         event=new FkActionEvent(t, data, acc,act) ;
72                 }
73                 @Override
74                 public void run() {
75                         if( delegate != null )
76                         {
77                                 delegate.fkActionEvent(event);
78                         }
79                 }
80         }
81         
82         
83         private Boolean checkState()
84         {
85
86                 int t=0;
87                 String msg="";
88                 Boolean stateOk=false;
89
90                 try {
91                         com.serialPort.writeByte((byte)SPACE_KEY);
92                         while( t < 100 )
93                         {
94                                 t++;
95                                 Thread.sleep(5);
96                                 
97                                 if( com.serialPort.getInputBufferBytesCount() > 0 )
98                                 {
99                                         msg += com.serialPort.readString();
100                                         if( msg.endsWith("\r\n>") )
101                                         {
102                                                 stateOk=true;
103                                                 msg="";
104                                                 break;
105                                         }
106                                 }
107                                 
108                         }
109                 
110                 } catch(Exception e)
111                 {
112                         stateOk=false;
113                 }
114                 flushSerial();
115                 if( !stateOk )
116                 {
117                         return(false);
118                 }
119                 return(true);
120                 
121         }
122         
123         private class TrigTask implements Runnable
124         {
125                 private Account acc;
126                 private char action;
127                 private FkActionEventListener delegate;
128                 public TrigTask(Account ac, char act, FkActionEventListener d )
129                 {
130                         acc=ac;
131                         action=act;
132                         delegate=d;
133                 }
134                 
135                 @Override
136                 public void run() {
137                         
138                         int t=0;
139                         String msg = "";
140
141
142                         try {
143                         
144                                 //First check that we get a prompt
145                                 if( !checkState() )
146                                 {
147                                         Display.getDefault().asyncExec( new FkActionEventMsg(delegate, FkActionEventListener.FkActionEventType.STATE_ERROR, "EXCEPTION",acc,action) );
148                                         return;
149                                 }
150
151                                 //if it's not '%' we need to type which action.
152                                 if(action != '%' )
153                                 {
154         
155                                                 //If the action is to delete or override, we start by deleting the account number.
156                                                 //Those commands are xd or xo so we type an x before the action.
157                                                 if( action == 'd' || action == 'o' )
158                                                 {
159                                                         com.serialPort.writeByte((byte)'x');
160                                                 }
161                                                 com.serialPort.writeByte((byte)action);
162         
163                                 }
164                         
165                                 com.serialPort.writeBytes(acc.num.toLowerCase().getBytes());
166                 
167                                 if( action == 'd' || action == 'o' )
168                                 {
169                                         com.serialPort.writeByte((byte)'y');
170                                 }                               
171                                 
172                                 Thread.sleep(200);
173
174                                 
175                                 t=0;
176                                 while( t < 1200 )
177                                 {
178                                         t++;
179                                         Thread.sleep(50);
180                                         if( com.serialPort.getInputBufferBytesCount() > 0 )
181                                         {
182                                                 msg += com.serialPort.readString();
183                                                 //System.out.println( msg );
184                                                 if( msg.contains("[done]") || msg.contains("[deleted]") )
185                                                 {
186                                                         if( action == 'd' )
187                                                         {
188                                                                 list.remove( acc );
189                                                         }
190                                                         Display.getDefault().asyncExec( new FkActionEventMsg(delegate, FkActionEventListener.FkActionEventType.ACTION_OKAY, msg, acc, action) );
191                                                         return;
192                                                 } else if( msg.contains("[abort]") )
193                                                 {
194                                                         //System.out.println("FkManager: Action Abort");;
195                                                         Display.getDefault().asyncExec( new FkActionEventMsg(delegate, FkActionEventListener.FkActionEventType.ACTION_ABORTED, msg,acc,action) );
196                                                         return;
197                                                 }
198                                         }
199                                 }
200                                 Display.getDefault().asyncExec( new FkActionEventMsg(delegate, FkActionEventListener.FkActionEventType.ACTION_ERROR, msg,acc,action) );
201
202                         } catch (Exception e1) {
203                                 System.out.println("TrigTask Exception:");
204                                 e1.printStackTrace();
205                                 Display.getDefault().asyncExec( new FkActionEventMsg(delegate, FkActionEventListener.FkActionEventType.ACTION_ERROR, "EXCEPTION",acc,action) );
206                         }
207                         
208                 }
209                 
210         }
211         
212         public void trig(Account acc, char action, FkActionEventListener delegate)
213         {
214                 TrigTask trigTask = new TrigTask(acc,action,delegate);
215                 new Thread(trigTask).start();
216         }
217         
218         
219         
220         private class SortByName implements Comparator<Account>
221         {
222                 @Override
223                 public int compare(Account o1, Account o2) {
224                         return o1.name.compareTo(o2.name);
225                 }
226         }
227         
228         private class SortById implements Comparator<Account>
229         {
230                 @Override
231                 public int compare(Account o1, Account o2) {
232                         int a = Integer.valueOf(o1.num, 16);
233                         int b = Integer.valueOf(o2.num, 16);
234                         return( a - b );
235                 }
236         }
237         
238         
239         
240         public void listAddAcc(String num, String name)
241         {
242                 list.addElement( new Account(num,name) );
243                 
244                 Collections.sort(list, sortMethod);
245         }
246         
247         public void listClear()
248         {
249                 list.clear();
250         }
251         
252         public Vector<Account> getList()
253         {
254                 return(list);
255         }
256         
257         public void getCurrentLayout()
258         {
259                 
260         }
261         
262         public void getAvailableLayouts()
263         {
264                 
265         }
266         
267         public void setLayout(int num)
268         {
269                 
270         }
271
272         @Override
273         public void actionPerformed(ActionEvent e) {
274                 Account f=null;
275                 for( Account a : list )
276                 {
277                         if( a.num.compareTo( e.getActionCommand().substring(1, 3)) == 0 )
278                         {
279                                 f=a;
280                                 break;
281                         }
282                 }
283                 if(f!=null)
284                 {
285                         trig(f, e.getActionCommand().charAt(0), null);
286                 }
287                 
288         }
289
290         public void setCurrentLayout(String str) {
291                 System.out.println("FkManager: Got current layout:" + str );
292                 
293         }
294         
295         private class NewAccountTask implements Runnable
296         {
297                 private String seq;
298                 private Account acc;
299                 FkActionEventListener delegate;
300                 public NewAccountTask(String sequence, FkActionEventListener d, String accountName)
301                 {
302                         seq=sequence;
303                         delegate=d;
304                         acc = new Account( "00", accountName );
305                         System.out.println("NewAccountTask ctor");
306                 }
307                 @Override
308                 public void run() {
309                         System.out.println("NewAccountTask run");
310                         Boolean noTimeOut = false;
311
312                         //First check that we get a prompt
313                         if( !checkState() )
314                         {
315                                 Display.getDefault().asyncExec( new FkActionEventMsg(delegate, FkActionEventListener.FkActionEventType.STATE_ERROR, "EXCEPTION",acc,'A') );
316                                 return;
317                         }
318                         
319                         String data="";
320                         int timeOut;
321                         try {                   
322                         //First type x a and wait for account title
323                                 
324                                 com.serialPort.writeByte((byte)'x');
325                                 com.serialPort.writeByte((byte)'a');
326                                 Display.getDefault().asyncExec( new FkActionEventMsg(delegate, FkActionEventListener.FkActionEventType.ACTION_WAITING, "WAITING",acc,'A') );
327
328                                 timeOut = 6000;
329                                 while(timeOut > 0)
330                                 {
331                                         if( com.serialPort.getInputBufferBytesCount() > 0 )
332                                         {
333                                                 String in = com.serialPort.readString(); 
334                                                 data += in;
335                                                 System.out.println("Datain:" +in);
336                                                 if( data.contains("Account Title, (0-31):") )
337                                                 {
338                                                         System.out.println("Found");
339                                                         break;
340                                                 }
341                                         } else {
342                                                 timeOut -= 50;
343                                                 Thread.sleep(50);
344                                         }
345                                 }
346                                 
347                                 if(timeOut > 0 )
348                                 {
349                                         Display.getDefault().asyncExec( new FkActionEventMsg(delegate, FkActionEventListener.FkActionEventType.ACTION_WORKING, "WORKING",acc,'A') );
350
351                                         for(int p=0; p < seq.length();p++)
352                                         {
353
354                                                 if( com.serialPort.getOutputBufferBytesCount() > 1 )
355                                                 {
356                                                         Thread.sleep(100);
357                                                         System.out.println("[SLEEP]");
358                                                 } else {
359                                                         if( seq.charAt(p) == PAUSE_CODE)
360                                                         {
361                                                                 Thread.sleep(100);
362                                                                 System.out.println("[DELAY]");
363                                                         } else {
364                                                                 if( seq.charAt(p) == ENTER_KEY )
365                                                                 {
366                                                                         System.out.println( "[ENTER]" );
367                                                                 } else {
368                                                                         System.out.println( "Type from pos ("+p+"):" + seq.charAt(p));
369                                                                 }
370         
371                                                                 com.serialPort.writeByte( (byte)seq.charAt(p) );
372                                                                 Thread.sleep(5);
373                                                         }
374                                                         
375                                                 }
376                                                 
377                                                 if(  com.serialPort.getInputBufferBytesCount() > 0 )
378                                                 {
379                                                         System.out.print("Reading "+com.serialPort.getInputBufferBytesCount()+ " bytes: ");
380                                                         data="";
381                                                         while( com.serialPort.getInputBufferBytesCount() > 0 )
382                                                         {
383                                                                 String in = com.serialPort.readString();
384                                                                 data += in;
385                                                                 
386                                                         }
387                                                         if( data.contains("[generate]") )
388                                                         {
389                                                                 noTimeOut=true;
390                                                                 System.out.println("1: noTimeOut");
391                                                         }                                                       
392                                                         System.out.println(data);
393                                                 }
394                                         }//While typing
395                                         System.out.println("All chars typed, waiting for [save entry ");
396                                         
397                                         int step=0;
398                                         
399                                         timeOut = 30000;
400                                         while( timeOut > 0 || noTimeOut )
401                                         {
402                                                 
403                                                 if( com.serialPort.getInputBufferBytesCount() > 0 )
404                                                 {
405                                                         String in = com.serialPort.readString();
406                                                         //System.out.println("Read>"+in);
407                                                         data += in;
408                                                         System.out.println("Data:"+data);
409                                                         
410                                                         //Check for abort first, in that case, we don't want to do anything.
411                                                         if( data.contains("[abort]") )
412                                                         {
413                                                                 Display.getDefault().asyncExec( new FkActionEventMsg(delegate, FkActionEventListener.FkActionEventType.ACTION_ABORTED, "ERROR:"+data,null,'A') );
414                                                                 return;
415                                                         }
416                                                         
417                                                         //If we're generating a password, we don't want to timeout
418                                                         if( data.contains("[generate]") )
419                                                         {
420                                                                 noTimeOut=true;
421                                                                 System.out.println("2: noTimeOut");
422                                                                 
423                                                         }
424                                                         
425                                                         //If we're at step0 and have the saveentry string and there's a ] after it, we're good to fetch the account number.
426                                                         if( step==0 && data.contains("[save entry ") && (data.lastIndexOf(']') > data.lastIndexOf("[save entry ")) )
427                                                         {
428                                                                 int begin = data.lastIndexOf("[save entry ")+12;
429                                                                 String subStr = data.substring(begin);
430                                                                 int end = subStr.indexOf(']');
431                                                                 subStr = subStr.substring(0,end);
432                                                                 if( subStr.length()==1)
433                                                                 {
434                                                                         subStr = "0"+subStr;
435                                                                 }
436                                                                 acc.num = subStr;
437                                                                 listAddAcc( acc.num, acc.name);
438                                                                 System.out.println("Account: "+acc.num+" " + acc.name);
439                                                                 
440                                                                 //Cut data, so that the [done] step1 looks for will not be the one after [generate].
441                                                                 data = data.substring(begin+end);
442                                                                 
443                                                                 System.out.println("Found [save entry, looking for done.");
444                                                                 step++;
445                                                         }
446                                                         
447                                                         if( step==1 && data.contains("[done]") )
448                                                         {
449                                                                 System.out.println("Found [done] in: {"+data+"}");
450                                                                 Display.getDefault().asyncExec( new FkActionEventMsg(delegate, FkActionEventListener.FkActionEventType.ACTION_OKAY, "DONE:"+data,acc,'A') );
451                                                                 return;
452                                                         }
453
454                                                 } else {
455                                                         Thread.sleep(50);
456                                                         timeOut -= 50;
457                                                 }
458                                         } //While !timeout 
459                                 } //If !timeout
460                                 
461                                 Display.getDefault().asyncExec( new FkActionEventMsg(delegate, FkActionEventListener.FkActionEventType.ACTION_ABORTED, "TIMEOUT:"+data,null,'A') );
462
463                         } catch (Exception e) {
464                                 Display.getDefault().asyncExec( new FkActionEventMsg(delegate, FkActionEventListener.FkActionEventType.ACTION_ERROR, "EXCEPTION",null,'A') );
465                         }
466                         
467                 }
468
469                 
470         }
471
472         private void flushSerial() {
473                 try {
474                         Thread.sleep(10);
475                         com.serialPort.purgePort(SerialPort.PURGE_RXCLEAR | SerialPort.PURGE_TXCLEAR);
476                         
477                         System.out.println("Flushed "+com.serialPort.getInputBufferBytesCount()+" bytes.");
478                         while( com.serialPort.getInputBufferBytesCount() > 0 )
479                         {
480                                 com.serialPort.readBytes();
481                         }
482                         
483                 } catch(Exception e)
484                 {
485                         System.out.println("FkManager flushSerial Exception:"+e.getMessage() );
486                 }
487                 
488         }       
489         
490         public void createAccount(String strAccountName, String strUserName,
491                         Boolean autoPassword, int autoPassLen, Boolean autoPassAllSpecials,
492                         String autoPassSpecials, String strPassword, Boolean seperatorTab,
493                         FkActionEventListener delegate) {
494                         
495                         StringBuilder sb = new StringBuilder(256);
496                 
497                         
498                         
499                         sb.append(strAccountName);
500                         sb.append(ENTER_KEY);
501                         sb.append(PAUSE_CODE);
502                         sb.append(strUserName);
503                         sb.append(ENTER_KEY);
504                         sb.append(PAUSE_CODE);
505                         
506                         if( autoPassword )
507                         {
508                                 sb.append('2'); //Select automatic password
509                                 sb.append(PAUSE_CODE);
510                                 sb.append(autoPassLen);
511                                 sb.append(ENTER_KEY);
512
513                                 
514                                 if( autoPassAllSpecials )
515                                 {
516                                         sb.append('1'); //Allow all characters
517                                 } else {
518                                         if( autoPassSpecials.length() > 0 )
519                                         {
520                                                 sb.append('2'); //Allow only characters specified below
521                                                 sb.append(PAUSE_CODE);
522                                                 sb.append(autoPassSpecials);
523                                                 sb.append(ENTER_KEY);
524                                         } else {
525                                                 sb.append('3'); // Allow no special characters
526                                         }
527                                 }
528                         } else {
529                                 //Manual entered password
530                                 sb.append('1'); // Select manual password
531                                 sb.append(PAUSE_CODE);
532                                 sb.append(strPassword);
533                                 sb.append(ENTER_KEY);
534                         }
535                         
536                         sb.append(PAUSE_CODE);
537
538                         //Tab/Enter sep
539                         if( seperatorTab )
540                         {
541                                 sb.append('1'); //Select tab seperator
542                         } else {
543                                 sb.append('2'); //Select enter seperator
544                         }
545                         
546                         String seq = sb.toString();
547                         
548                         System.out.println("Seq ["+seq.replace(PAUSE_CODE, 'ø').replace(ENTER_KEY, 'å')+"]");
549                         
550                         NewAccountTask newTask = new NewAccountTask(seq, delegate, strAccountName);
551                         new Thread(newTask).start();                    
552                 
553         }
554
555         public void sortById(boolean byId) {
556                 if( byId )
557                 {
558                         sortMethod = new SortById();
559                 } else {
560                         sortMethod = new SortByName();
561                 }
562                 if(list != null )
563                 {
564                         Collections.sort(list, sortMethod);
565                 }
566         }
567
568
569 }