Subversion Repositories Projects

Rev

Rev 213 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
206 ligi 1
/********************************************************************************************************************************
2
 *                                                                    
3
 * Abstaction Layer to Communicate via J2ME and Bluetooth with the FlightCtrl of the MikroKopter Project (www.mikrokopter.de )  
4
 *                                                
5
 * Author:        Marcus -LiGi- Bueschleb          
6
 *
7
 * see README for further Infos
8
 *
9
 *
10
 *******************************************************************************************************************************/
11
 
12
 
13
package org.ligi.ufo;
14
 
15
 
16
//#ifdef j2me
17
//# import javax.microedition.io.*;
18
//#endif
19
 
20
//#ifdef android
21
import android.util.Log;
22
//#endif
23
 
24
 
25
 
26
import java.io.*;
27
 
28
 
29
public class MKCommunicator
30
    implements Runnable
31
{
32
    /***************** Section: public Attributes **********************************************/
33
    public boolean connected=false; // flag for the connection state
34
 
35
    public String mk_url=""; // buffer the url which is given in the constuctor for reconnectin purposes
36
 
37
    public final static int DATA_BUFF_LEN = 20; // in lines
38
 
39
    public String[] data_buff;
40
 
41
    //    boolean do_log=false;
42
    boolean do_log=true;
43
 
44
    int data_buff_pos=0;
45
 
46
    public byte user_intent=0;
47
public final static int[] crc16_table = {
48
 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
49
 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
50
 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
51
 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
52
 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
53
 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
54
 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
55
 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
56
 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
57
 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
58
 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
59
 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
60
 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
61
 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
62
 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
63
 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
64
 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
65
 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
66
 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
67
 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
68
 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
69
 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
70
 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
71
 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
72
 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
73
 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
74
 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
75
 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
76
 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
77
 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
78
 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
79
 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
80
 };
81
 
82
    public void log(String str)
83
    {
84
//#ifdef android
85
if (do_log)     Log.d("MK-Comm",str);
86
//#endif
87
    }
88
 
89
    public int CRC16(int ch, int crc)
90
    { return crc16_table[((crc >> 8) ^ (ch)) & 0xFF] ^ (crc << 8);
91
    }
92
 
93
 
94
    public int conn_time_in_s()
95
    {
96
        if (connected)
97
            return (int)((System.currentTimeMillis()-connection_start_time)/1000);
98
        else
99
            return 0;
100
    }
101
    public final static int BOOTLOADER_STAGE_NONE=0;
102
    public final static int BOOTLOADER_STAGE_GOT_MKBL=1;
103
 
104
    int bootloader_stage= BOOTLOADER_STAGE_NONE;
105
 
106
    public MKLCD LCD;
107
    public MKVersion version;
108
    public MKDebugData debug_data;
109
 
110
    public MKGPSPosition gps_position;
111
 
112
    public MKStickData stick_data;
113
    public MKParamsParser params;
114
    public MKWatchDog watchdog;
115
    public MKProxy proxy=null;
116
    public MKStatistics stats ;
117
    //    public DUBwiseDebug debug;
118
 
119
    public UFOProber    ufo_prober;
120
    public long connection_start_time=-1;
121
 
122
 
123
    public String error_str = null;
124
 
125
 
126
    public final static int FC_SLAVE_ADDR              = 'a'+1;
127
    public final static int NAVI_SLAVE_ADDR            = 'a'+2;
128
    public final static int MK3MAG_SLAVE_ADDR          = 'a'+3;
129
 
130
 
131
 
132
 
133
    /****************** Section: private Attributes **********************************************/
134
//#ifdef j2me
135
//#    private javax.microedition.io.StreamConnection connection;
136
//#endif
137
 
138
//#ifdef android
139
//    java.net.Socket connection;
140
    java.net.Socket connection;
141
//#endif
142
 
143
 
144
    private java.io.InputStream reader;    
145
    private java.io.OutputStream writer;    
146
 
147
 
148
 
149
    public String name;
150
    //    DUBwise root;
151
 
152
 
153
    private boolean sending=false;
154
    private boolean recieving=false;
155
 
156
 
157
 
158
    /******************  Section: public Methods ************************************************/
159
    public MKCommunicator()  
160
    {
161
 
162
        data_buff=new String[DATA_BUFF_LEN];
163
        for (int i=0;i<DATA_BUFF_LEN;i++)
164
            data_buff[i]="";
165
        //      debug=debug_;
166
        //      root=root_;
167
        version=new MKVersion();
168
        debug_data=new MKDebugData();
169
        stick_data=new MKStickData();
170
        params=new MKParamsParser();
171
        LCD= new MKLCD(this);
172
        watchdog=new MKWatchDog(this);
173
        gps_position=new MKGPSPosition();
174
        stats = new MKStatistics();
175
        proxy =new MKProxy(this);
176
        ufo_prober=new UFOProber();
177
        new Thread( this ).start(); // fire up main Thread 
178
    }
179
 
180
 
181
 
182
    public void write_raw(byte[] _data)
183
    {
184
        wait4send();
185
        sending=true;
186
        try {
187
        writer.write(_data,0,_data.length);
188
        writer.flush();
189
 
190
        stats.bytes_out+=_data.length;
191
        }
192
        catch ( Exception e){}
193
        sending=false;
194
    }
195
 
196
    public void do_proxy(String proxy_url)
197
    {
198
        proxy.connect(proxy_url);
199
    }
200
 
201
    //    int port;
202
 
203
    //  URL string: "btspp://XXXXXXXXXXXX:1" - the X-Part is the MAC-Adress of the Bluetooth-Device connected to the Fligth-Control
204
    public void connect_to(String _url,String _name)
205
    {
206
        //      port=_port;
207
        mk_url=_url; // remember URL for connecting / reconnecting later
208
        name=_name;
209
        force_disconnect=false;
210
        connected=false;
211
    }
212
 
213
    public boolean ready()
214
    {
215
        return (connected&&(version.major!=-1));
216
    }
217
 
218
 
219
    public String get_buff(int age)
220
    {
221
 
222
        age%=DATA_BUFF_LEN;
223
 
224
        if (age<=data_buff_pos)
225
            return ""+data_buff[data_buff_pos-age];
226
        else
227
            return ""+data_buff[DATA_BUFF_LEN+data_buff_pos-age];
228
 
229
 
230
    }
231
    /******************  Section: private Methods ************************************************/
232
    private void connect()
233
    {
234
        log("trying to connect to" + mk_url);
235
        try{
236
 
237
            // old call
238
            // connection = (StreamConnection) Connector.open(mk_url, Connector.READ_WRITE);
239
 
240
//#ifdef android
241
            connection = (new java.net.Socket(mk_url.split(":")[0],Integer.parseInt(mk_url.split(":")[1])));
242
            //.Socket 
243
 
244
            reader=connection.getInputStream();
245
            writer=connection.getOutputStream();
246
 
247
            String magic="conn:foo bar\r\n";
248
            writer.write(magic.getBytes());
249
            writer.flush();
250
 
251
//#else
252
 
253
//#         connection = (StreamConnection) Connector.open(mk_url);
254
 
255
//#         reader=connection.openInputStream();
256
//#         writer=connection.openOutputStream();
257
 
258
//#endif
259
            connection_start_time=System.currentTimeMillis();
260
            connected=true; // if we get here everything seems to be OK
261
 
262
            stats.reset();
263
 
264
            log("connecting OK");
265
        }
266
        catch (Exception ex)
267
            {
268
                // TODO difference fatal errors from those which will lead to reconnection
269
                log("Problem connecting" + "\n" + ex);
270
            }  
271
    }
272
 
273
    public int[] Decode64(byte[] in_arr, int offset,int len)
274
    {
275
        int ptrIn=offset;      
276
        int a,b,c,d,x,y,z;
277
        int ptr=0;
278
 
279
        int[] out_arr=new int[len];
280
 
281
        while(len!=0)
282
            {
283
                a=0;
284
                b=0;
285
                c=0;
286
                d=0;
287
                try {
288
                a = in_arr[ptrIn++] - '=';
289
                b = in_arr[ptrIn++] - '=';
290
                c = in_arr[ptrIn++] - '=';
291
                d = in_arr[ptrIn++] - '=';
292
                }
293
                catch (Exception e) {}
294
                //if(ptrIn > max - 2) break;     // nicht mehr Daten verarbeiten, als empfangen wurden
295
 
296
                x = (a << 2) | (b >> 4);
297
                y = ((b & 0x0f) << 4) | (c >> 2);
298
                z = ((c & 0x03) << 6) | d;
299
 
300
                if((len--)!=0) out_arr[ptr++] = x; else break;
301
                if((len--)!=0) out_arr[ptr++] = y; else break;
302
                if((len--)!=0) out_arr[ptr++] = z; else break;
303
            }
304
 
305
        return out_arr;
306
 
307
    }
308
 
309
    public void wait4send()
310
    {
311
        while(sending) //||recieving)
312
            sleep(50);
313
    }
314
 
315
 
316
    public void sleep(int time)
317
    {
318
        try { Thread.sleep(time); }
319
        catch (Exception e)  {   }
320
    }
321
 
322
    // FC - Function Mappers
323
 
324
    // send a version Request to the FC - the reply to this request will be processed in process_data when it arrives
325
    public void get_version()
326
    {
327
        stats.version_data_request_count++;
328
        send_command(0,'v');
329
    }
330
 
331
    public void set_gps_target(int longitude,int latitude)
332
    {
333
        int[] target=new int[8];
334
        target[0]= (0xFF)&(longitude<<24);
335
        target[1]= (0xFF)&(longitude<<16);
336
        target[2]= (0xFF)&(longitude<<8);
337
        target[3]= (0xFF)&(longitude);
338
        //      send_command(0,'s',target);
339
    }
340
 
341
    // send a MotorTest request - params are the speed for each Motor
342
    public void motor_test(int[] params)
343
    {
344
        stats.motortest_request_count++;
345
        send_command(FC_SLAVE_ADDR,'t',params);
346
    }
347
 
348
    public void send_keys(int[] params)
349
    {
350
        send_command(FC_SLAVE_ADDR,'k',params);
351
    }
352
 
353
    // get params
354
    public void get_params(int id)
355
    {
356
        wait4send();
357
        send_command(FC_SLAVE_ADDR,'q',id+1);
358
        stats.params_data_request_count++;
359
    }
360
 
361
   public void get_debug_name(int id)
362
    {
363
 
364
        wait4send();
365
        send_command(0,'a',id);
366
    }
367
 
368
 
369
    public void trigger_LCD_by_page(int page)
370
    {
371
        wait4send();
372
        send_command(0,'l',page);
373
        stats.lcd_data_request_count++;
374
    }
375
 
376
    public void trigger_debug()
377
    {
378
        if (sending||recieving) return; // its not that important - can be dropped
379
        send_command(0,'c');
380
    }
381
 
382
 
383
 
384
    public void switch_to_fc()
385
    {
386
        wait4send();
387
        send_command(NAVI_SLAVE_ADDR,'u',0);
388
        sleep(50);
389
        version=new MKVersion();
390
        LCD= new MKLCD(this);
391
    }
392
 
393
 
394
    public void switch_to_mk3mag()
395
    {
396
        wait4send();
397
        send_command(NAVI_SLAVE_ADDR   ,'u',1);
398
        sleep(50);
399
        version=new MKVersion();
400
        LCD= new MKLCD(this);
401
    }
402
 
403
    public void switch_to_navi()
404
    {
405
        wait4send();
406
        sending=true;
407
        try
408
            {
409
                writer.write( 27);
410
                writer.write( 27);
411
                writer.write( 0x55);
412
                writer.write( 0xaa);
413
                writer.write( 0);
414
                writer.write('\r');
415
                stats.bytes_out+=6;
416
                writer.flush();
417
            }
418
        catch (Exception e)  {   }
419
        sending=false;
420
 
421
        sleep(50);
422
        version=new MKVersion();
423
        LCD= new MKLCD(this);
424
    }
425
 
426
    public String[] flash_msgs;
427
        int msg_pos=0;
428
 
429
 
430
    public boolean bootloader_intension_flash=false;
431
    public void jump_bootloader()
432
    {
433
 
434
        msg_pos=0;
435
        bootloader_stage= BOOTLOADER_STAGE_NONE;
436
        flash_msgs=new String[100];
437
        flash_msgs[msg_pos++]="Initiializing Bootloader";
438
        wait4send();
439
        sending=true;
440
 
441
        try
442
            {
443
                int attempt=0;
444
 
445
                while(bootloader_stage!= BOOTLOADER_STAGE_GOT_MKBL)
446
                    {
447
                        flash_msgs[msg_pos]="attempt "+attempt;
448
                        attempt++;
449
                        send_command_nocheck((byte)FC_SLAVE_ADDR,'R',new int[0]);
450
                        writer.write( 27);
451
                        writer.flush();
452
 
453
                        sleep(20);
454
 
455
                        writer.write( 0xAA);
456
                        writer.flush();
457
 
458
                        sleep((attempt%2==0)?80:800); //800
459
                    }
460
                msg_pos++;
461
            }
462
 
463
        catch (Exception e)  {  
464
                flash_msgs[msg_pos++]="Exception:" +e.getMessage() ;
465
                flash_msgs[msg_pos++]=e.toString() ;
466
        }
467
 
468
        new Thread( this ).start(); // fire up main Thread 
469
    }
470
 
471
 
472
    public void get_error_str()
473
    {
474
        send_command(NAVI_SLAVE_ADDR,'e');
475
    }
476
 
477
    public void trigger_rcdata()
478
    {
479
        send_command(FC_SLAVE_ADDR,'p');
480
    }
481
 
482
 
483
    public void write_params()
484
    {
485
        params.update_backup();
486
        wait4send();
487
        send_command(FC_SLAVE_ADDR,'s',params.field_bak[params.act_paramset]);
488
    }
489
 
490
    public void send_command(int modul,char cmd)
491
    {
492
        send_command(modul,cmd,new int[0]);
493
    }
494
 
495
    public void send_command(int modul,char cmd,int param)
496
    {
497
        int[] params=new int[1];
498
        params[0]=param;
499
        send_command(modul,cmd,params);
500
    }
501
 
502
    public void send_command_nocheck(byte modul,char cmd,int[] params)
503
    {
504
//      char[] send_buff=new char[5 + (params.length/3 + (params.length%3==0?0:1) )*4]; // 5=1*start_char+1*addr+1*cmd+2*crc
505
 
506
        byte[] send_buff=new byte[3 + (params.length/3 + (params.length%3==0?0:1) )*4]; // 5=1*start_char+1*addr+1*cmd+2*crc
507
        send_buff[0]='#';
508
        send_buff[1]=modul;
509
        send_buff[2]=(byte)cmd;
510
 
511
        for(int param_pos=0;param_pos<(params.length/3 + (params.length%3==0?0:1)) ;param_pos++)
512
            {
513
                int a = (param_pos*3<params.length)?params[param_pos*3]:0;
514
                int b = ((param_pos*3+1)<params.length)?params[param_pos*3+1]:0;
515
                int c = ((param_pos*3+2)<params.length)?params[param_pos*3+2]:0;
516
 
517
                send_buff[3+param_pos*4] =  (byte)((a >> 2)+'=' );
518
                send_buff[3+param_pos*4+1] = (byte)('=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4)));
519
                send_buff[3+param_pos*4+2] = (byte)('=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6)));
520
                send_buff[3+param_pos*4+3] = (byte)('=' + ( c & 0x3f));
521
 
522
                //send_buff[3+foo]='=';
523
            }
524
 
525
        /*      for(int foo=0;foo<(params.length/3 + (params.length%3==0?0:1) )*4;foo++)
526
                {
527
                int a = (foo<params.length) params[foo];
528
                int a = params[foo];
529
 
530
                //send_buff[3+foo]='=';
531
                }
532
        */
533
        try
534
            {
535
                int tmp_crc=0;
536
                for ( int tmp_i=0; tmp_i<send_buff.length;tmp_i++)
537
                    tmp_crc+=(int)send_buff[tmp_i];
538
 
539
                writer.write(send_buff,0,send_buff.length);
540
                tmp_crc%=4096;
541
 
542
                writer.write( (char)(tmp_crc/64 + '='));
543
                writer.write( (char)(tmp_crc%64 + '='));
544
                writer.write('\r');
545
                stats.bytes_out+=send_buff.length+3;
546
                writer.flush();
547
            }
548
        catch (Exception e)
549
            { // problem sending data to FC
550
            }
551
 
552
    }
553
    // send command to FC ( add crc and pack into pseudo Base64
554
    public void send_command(int modul,char cmd,int[] params)
555
    {
556
 
557
        //      if (modul==0) return;
558
        sending=true;
559
        send_command_nocheck((byte)modul,cmd,params);
560
        sending=false;
561
    }
562
 
563
 
564
    public int slave_addr=-1;
565
 
566
 
567
    public int UBatt()
568
    {
569
        if (ufo_prober.is_mk())
570
            return debug_data.UBatt();
571
        else  if (ufo_prober.is_navi())
572
            return gps_position.UBatt;
573
 
574
        return -1;
575
 
576
    }
577
 
578
 
579
 
580
    public int SenderOkay()
581
    {
582
        if (ufo_prober.is_mk())
583
            return debug_data.SenderOkay();
584
        else  if (ufo_prober.is_navi())
585
            return gps_position.SenderOkay;
586
 
587
        return -1;
588
 
589
    }
590
 
591
 
592
    public void process_data(byte[] data,int len)
593
    {
594
 
595
 
596
        log("command " +(char)data[2] );               
597
        switch((char)data[2])
598
            {
599
 
600
            case 'A': // debug Data Names
601
                stats.debug_names_count++;
602
                debug_data.set_names_by_mk_data(Decode64(data,3,len-3));
603
                break;
604
 
605
            case 'L': // LCD Data
606
                stats.lcd_data_count++;
607
                LCD.handle_lcd_data(Decode64(data,3,len-3));
608
 
609
                break;
610
 
611
            case 'D': // debug Data
612
                log("got debug data");
613
                stats.debug_data_count++;
614
                debug_data.set_by_mk_data(Decode64(data,3,len-3),version);
615
                log("processed debug data");
616
                break;
617
 
618
            case 'V': // Version Info
619
                stats.version_data_count++;
620
                slave_addr=data[1];
621
 
622
                switch(slave_addr)
623
                    {
624
                    case FC_SLAVE_ADDR:
625
                        ufo_prober.set_to_mk();
626
                        break;
627
 
628
                    case NAVI_SLAVE_ADDR:
629
                        ufo_prober.set_to_navi();
630
                        break;
631
 
632
                    case MK3MAG_SLAVE_ADDR:
633
                        //                      ufo_prober.set_to_mk();
634
                        ufo_prober.set_to_mk3mag();
635
                        break;
636
 
637
                    default:
638
                        ufo_prober.set_to_incompatible();
639
                        break;
640
                    }
641
 
642
 
643
                version.set_by_mk_data(Decode64(data,3,len-3));
644
                break;
645
 
646
            case 'w':
647
                stats.angle_data_count++;
648
 
649
                break;
650
 
651
 
652
            case 'Q':
653
                if (ufo_prober.is_mk())
654
                    {
655
                        stats.params_data_count++;
656
                        params.set_by_mk_data(Decode64(data,3,len-3));
657
                    }
658
                break;
659
 
660
            case 'P':
661
                stats.stick_data_count++;
662
                stick_data.set_by_mk_data(Decode64(data,3,20));
663
                break;
664
 
665
 
666
            case 'E':
667
                int[] dec_data=Decode64(data,3,len-3);
668
                error_str="";
669
                for(int foo=0;foo<20;foo++)
670
                    if (dec_data[foo]!=0)
671
                        error_str+=(char)dec_data[foo];
672
                break;
673
 
674
 
675
            case 'O':
676
                stats.navi_data_count++;
677
                log("got navi data(" + len +"):");
678
 
679
                gps_position.set_by_mk_data(Decode64(data,3,len-3),version);
680
 
681
                log("long:" + gps_position.Longitude);
682
                log("lat:" + gps_position.Latitude);
683
 
684
                break;
685
 
686
 
687
                // Error from Navi
688
 
689
 
690
            default:
691
                stats.other_data_count++;
692
                break;
693
 
694
            }
695
 
696
    }
697
 
698
    public boolean force_disconnect=true;
699
 
700
    public void close_connections(boolean force)
701
    {
702
        //      if ((!force)&&root.canvas.do_vibra) root.vibrate(500);
703
        force_disconnect=force;
704
        try{ reader.close(); }
705
        catch (Exception inner_ex) { }
706
 
707
        try{ writer.close(); }
708
        catch (Exception inner_ex) { }
709
 
710
//#ifdef j2me
711
//#     try{ connection.close(); }
712
//#     catch (Exception inner_ex) { }
713
//#endif
714
        ufo_prober.set_to_none();
715
        stats.reset();
716
        connected=false;
717
        version=new MKVersion();
718
    }
719
 
720
    // Thread to recieve data from Connection
721
    public void run()
722
    {
723
 
724
        if (bootloader_stage==BOOTLOADER_STAGE_GOT_MKBL)
725
            {
726
            try {
727
                        flash_msgs[msg_pos++]="reading avr_sig";
728
 
729
                        writer.write( 't');
730
                        writer.flush();
731
 
732
                        int avr_sig=reader.read();
733
                        flash_msgs[msg_pos++]="got avr sig " + avr_sig;
734
 
735
 
736
                        if (reader.read()!=0)
737
                            throw new Exception("val after avrsig isnt 0");
738
 
739
                        if ((avr_sig!=0x74)&&(avr_sig!=224)&&(avr_sig!=120))
740
                            throw new Exception("avr sig" + avr_sig + " unknown");
741
 
742
                        writer.write('T');
743
                        //              writer.flush();
744
                        writer.write(avr_sig);   // set devicetyp = 0x74 oder 0x76  
745
                        writer.flush();
746
 
747
                        if (reader.read()!=0x0d)
748
                            throw new Exception("cant get buffer size");
749
 
750
                        writer.write('V');
751
                        writer.flush();
752
 
753
                        int bl_version_major=reader.read();
754
                        int bl_version_minor=reader.read();
755
 
756
                        flash_msgs[msg_pos++]="BL Version " + bl_version_major+"."+bl_version_minor;
757
 
758
 
759
                        writer.write('b');
760
                        writer.flush();
761
 
762
                        if (reader.read()!='Y')
763
                            throw new Exception("cant get buffer size");
764
 
765
                        int send_buff_size1=reader.read();
766
                        int send_buff_size2=reader.read();
767
                        int send_buff_size=send_buff_size1*0x100+send_buff_size2;
768
 
769
                        flash_msgs[msg_pos++]="BUFF Size:" + send_buff_size;
770
                        //                      if (send_buff_size>128)
771
                        //    send_buff_size=128;
772
                if (bootloader_intension_flash)
773
                    {          
774
 
775
                        byte[] flash_buff =new byte[send_buff_size]; ///!!
776
 
777
 
778
                        flash_msgs[msg_pos++]="Opening firmware ..";
779
 
780
 
781
                        InputStream in;
782
                        try {
783
                            in=this.getClass().getResourceAsStream((avr_sig==224)?"/navi.bin":((avr_sig==120)?"mk3.bin":"/fc.bin"));       
784
                        }
785
 
786
                        catch (Exception e) {               throw new Exception(" cant open firmware");                 }
787
 
788
 
789
                        int firmware_size= ((int)in.read()<<24) |((int)in.read()<<16) | ((int)in.read()<<8) | ((int)in.read()&0xff) ;
790
 
791
 
792
                        flash_msgs[msg_pos++]=".. open with " + firmware_size + "bytes";
793
 
794
 
795
 
796
 
797
 
798
                        //      if (true) throw new Exception("before erasing" );               
799
 
800
                        flash_msgs[msg_pos++]="Erasing Flash ..";
801
                        writer.write('e');
802
                        writer.flush();
803
 
804
                        if (reader.read()!=0x0d)
805
                            throw new Exception("cant erase flash");
806
 
807
                        flash_msgs[msg_pos]+="OK";
808
 
809
 
810
                        writer.write('A');
811
                        writer.write(0);
812
                        writer.write(0);
813
                        writer.flush();
814
 
815
                        if (reader.read()!=0x0d)
816
                            throw new Exception("cant set addr");
817
 
818
                        flash_msgs[msg_pos++]="addr set";
819
 
820
 
821
                        int blocks2write=((firmware_size/send_buff_size));
822
                        if ((firmware_size%send_buff_size)>0)
823
                            blocks2write++;
824
 
825
                        for ( int block=0; block<blocks2write; block ++)
826
                            {
827
                                int hex_bytes_read=in.read(flash_buff,0,send_buff_size);
828
 
829
                                flash_msgs[msg_pos]="bl:" + block + "/" + blocks2write + " si:"+hex_bytes_read ;
830
 
831
 
832
                                writer.write('B');
833
                                writer.write((hex_bytes_read>>8)& 0xFF);
834
                                writer.write((hex_bytes_read)& 0xFF);
835
                                writer.write('F');
836
                                writer.flush();
837
 
838
 
839
                                writer.write(flash_buff,0,hex_bytes_read);
840
                                writer.flush();                                
841
 
842
 
843
                                if (avr_sig==224)
844
                                    {
845
                                        int crc=0xFFFF;
846
                                        for (int crc_pos=0;crc_pos<hex_bytes_read;crc_pos++)
847
                                            crc=CRC16(flash_buff[crc_pos],crc);
848
                                        writer.write(crc>>8);
849
                                        writer.write(crc&0xff);
850
                                        writer.flush();
851
                                    }
852
                                        //  flash_msgs[msg_pos]+="ok";
853
                                        //                              writer.flush();
854
 
855
 
856
 
857
                                if (reader.read()!=0x0d)
858
                                        throw new Exception("abort write at block"+block);
859
 
860
 
861
 
862
                                //                             sleep(1000);
863
                                                    }
864
                        //              flash_msgs[msg_pos]="bl:" + block + "/" + blocks2write + " si:"+hex_bytes_read ;
865
                        /*
866
 
867
                        int inp=0;
868
                        int block=0;
869
                        while (inp!=-1)
870
                            {
871
                                int flash_buff_pos=0;
872
                                int crc=0xFFFF;
873
 
874
                                while ((flash_buff_pos<send_buff_size)&&(inp!=-1))
875
                                    {
876
                                        inp=in.read();
877
                                        if (inp!=-1)
878
                                            {
879
                                                crc=CRC16(inp,crc);
880
                                                flash_buff[flash_buff_pos++]=(byte)inp;
881
                                            }
882
                                    }
883
                                //                              flash_msgs[msg_pos]="block" + block + "size:"+flash_buff_pos;
884
 
885
                                block++;        
886
 
887
                                boolean block_fin=false;
888
 
889
 
890
                                while(!block_fin)
891
                                    {
892
 
893
                                        writer.write('B');
894
                                        writer.write((flash_buff_pos>>8)& 0xFF);
895
                                        writer.write((flash_buff_pos)& 0xFF);
896
                                        writer.write('F');
897
                                        writer.flush();
898
 
899
                                        //                                      int ret_v=-1;
900
 
901
                                        writer.write(flash_buff,0,flash_buff_pos);
902
                                        flash_msgs[msg_pos]="bl:" + block + "si:"+flash_buff_pos ;
903
 
904
                                        writer.flush();                                
905
                                        //                                  flash_msgs[msg_pos]+="wtc";
906
 
907
 
908
                                        // append crc if navi
909
                                        if (avr_sig==224)
910
                                            {
911
                                                writer.write(crc>>8);
912
                                                writer.write(crc&0xff);
913
                                                writer.flush();
914
                                            }
915
                                        //  flash_msgs[msg_pos]+="ok";
916
                                        //                              writer.flush();
917
                                        //                      if (reader.read()!=0x0d)
918
                                        //                                  throw new Exception("abort write at block"+block);
919
 
920
 
921
                                        //ret_v=reader.read();
922
                                        //                                  flash_msgs[msg_pos]="ret"+ret_v + "crc"+crc;
923
 
924
                                        if (reader.read()==0x0d)
925
                                            block_fin=true;
926
 
927
                                    }
928
 
929
                            }
930
                        */
931
                        flash_msgs[++msg_pos]="written last block ";
932
                        msg_pos++;
933
                        flash_buff=null;
934
 
935
                        ufo_prober.set_to_none();
936
                        stats.reset();
937
                        version=new MKVersion();
938
                        System.gc();
939
                    }
940
                else // bootloader intension clear settings
941
                    {
942
 
943
                        flash_msgs[msg_pos]="reset params ..";
944
                        writer.write('B');
945
                        writer.write(0);
946
                        writer.write(4);
947
                        writer.write('E');
948
                        writer.flush();
949
 
950
                        writer.write(0xFF);
951
                        writer.write(0xFF);
952
                        writer.write(0xFF);
953
                        writer.write(0xFF);
954
                        writer.flush();
955
                        flash_msgs[msg_pos++]+=" done";
956
                    }
957
 
958
            flash_msgs[msg_pos++]="Exiting Bootloader" ;
959
            params=new MKParamsParser();
960
            try{
961
                writer.write('E');
962
                writer.flush();
963
            }
964
            catch (Exception e)  {  
965
                flash_msgs[msg_pos++]="cant exit bootloader" ;
966
            }
967
            flash_msgs[msg_pos++]="Exit BL done" ;         
968
 
969
 
970
            }
971
 
972
            catch (Exception e)  {  
973
                flash_msgs[msg_pos++]="Fail:" +e.getMessage() ;
974
 
975
 
976
            flash_msgs[msg_pos++]="Exiting Bootloader" ;
977
            params=new MKParamsParser();
978
            try{
979
                writer.write('E');
980
                writer.flush();
981
            }
982
            catch (Exception e2)  {  
983
                flash_msgs[msg_pos++]="cant exit bootloader" ;
984
            }
985
            flash_msgs[msg_pos++]="Exit BL done" ;
986
 
987
 
988
 
989
                close_connections(false);
990
            }
991
 
992
 
993
            sending=false;
994
            }
995
 
996
 
997
        byte[] data_set=new byte[1024];
998
        int data_set_pos=0;
999
        byte[] data_in_buff=new byte[2048];
1000
 
1001
        int input;
1002
        int pos=0;
1003
 
1004
 
1005
 
1006
 
1007
 
1008
        log("Thread started");
1009
        while(true)
1010
            {
1011
 
1012
                if (!connected)
1013
                    {
1014
                        if (!force_disconnect) connect();
1015
                        sleep(100);
1016
                    }
1017
                else
1018
                    try{
1019
 
1020
                        /*             
1021
                                while(sending)
1022
                                {try { Thread.sleep(50); }
1023
                                catch (Exception e)  {   }
1024
                                }
1025
                        */
1026
 
1027
                        recieving=true;
1028
                        int read_count =reader.read(data_in_buff,0,reader.available());
1029
                        log("Connected - reading data " + read_count);         
1030
                        //      pos=0;
1031
                        input=0;
1032
                        //data_buff[data_buff_pos]="";
1033
                        // recieve data-set
1034
                        if (read_count==0) sleep(50);
1035
 
1036
                        //                      int read_count =reader.read(data_in_buff,0,reader.available());
1037
                        stats.bytes_in+=read_count;
1038
                        if (read_count>0)
1039
                            {
1040
                                log("read" + read_count + " ds_pos" + data_set_pos);           
1041
 
1042
                                for ( pos=0;pos<read_count;pos++)
1043
                                    {
1044
                                        if (data_in_buff[pos]==13)
1045
                                            {
1046
                                                data_buff[data_buff_pos]=""+data_buff_pos+ "--"+new String(data_set, 0, data_set_pos);
1047
                                                data_buff_pos++;
1048
                                                data_buff_pos%=DATA_BUFF_LEN;
1049
 
1050
 
1051
                                                try{process_data(data_set,data_set_pos); }
1052
                                                catch (Exception e)
1053
                                                    {                  
1054
                                                        log(".. problem processing");
1055
                                                        log(e.toString());
1056
                                                        }
1057
 
1058
 
1059
 
1060
 
1061
                                                proxy.write(data_set,0,data_set_pos);
1062
                                                //                                                      proxy.writer.write('\r');
1063
                                                //proxy.writer.write('\n');
1064
                                                //proxy.writer.flush();
1065
                                                /*
1066
                                                if (proxy!=null)
1067
                                                    {
1068
 
1069
 
1070
 
1071
                                                    }
1072
                                                */
1073
                                                data_set_pos=0;
1074
 
1075
                                            }
1076
                                        else
1077
                                            {
1078
                                                data_set[data_set_pos++]=data_in_buff[pos];
1079
 
1080
 
1081
 
1082
                                                if ( (data_set_pos>4) && (data_set[data_set_pos-4]==(byte)'M') && (data_set[data_set_pos-3]==(byte)'K')  && (data_set[data_set_pos-2]==(byte)'B') && (data_set[data_set_pos-1]==(byte)'L'))
1083
                                                    {
1084
                                                        bootloader_stage= BOOTLOADER_STAGE_GOT_MKBL;
1085
                                                        return;
1086
                                                    }
1087
 
1088
                                            }
1089
 
1090
                                    }
1091
 
1092
 
1093
                            }
1094
                        else
1095
                            sleep(50);
1096
                        /*
1097
                        while ((input != 13)) //&&(input!=-1))
1098
                            {
1099
                                {
1100
                                    //log("pre read");         
1101
                                    log(""+reader.available());
1102
                                    input = reader.read() ;
1103
                                    log("Byte rcv" + input +"pos"+ pos);               
1104
 
1105
                                    proxy.write(input);
1106
 
1107
                                    data_buff[data_buff_pos]+=(char)input;
1108
 
1109
                                    if ((data_buff[data_buff_pos].length()>3)&&(data_buff[data_buff_pos].substring(data_buff[data_buff_pos].length()-4,data_buff[data_buff_pos].length()).equals("MKBL")))
1110
                                        {
1111
                                            bootloader_stage= BOOTLOADER_STAGE_GOT_MKBL;
1112
                                            return;
1113
                                        }
1114
                                    if (input==-1) throw new Exception("disconnect");
1115
                                    else
1116
                                        {
1117
                                            stats.bytes_in++;
1118
                                            data_set[pos]=input;
1119
                                            pos++;
1120
                                        }
1121
                                }
1122
 
1123
                            }
1124
 
1125
 
1126
 
1127
                        data_buff_pos++;
1128
                        data_buff_pos%=DATA_BUFF_LEN;
1129
                        recieving=false;
1130
                        log("Data recieved (" + pos + "Bytes)");               
1131
                        log("processing ..");          
1132
                        */
1133
 
1134
                        /*
1135
                          if (proxy!=null)
1136
                          {
1137
                          proxy.writer.write('\r');
1138
                          proxy.writer.write('\n');
1139
                          proxy.writer.flush();
1140
                          }
1141
                        */
1142
                        /*if (pos>5)
1143
                            {
1144
                                try{process_data(data_set,pos); }
1145
                                catch (Exception e)
1146
                                    {                  
1147
                                        log(".. problem processing");
1148
                                        log(e.toString());
1149
                                    }
1150
 
1151
                                log(".. processing done");             
1152
                            }
1153
                        */
1154
                    }
1155
                    catch (Exception ex)
1156
                        {
1157
                            log("Problem reading from MK -> closing conn");
1158
                            log(ex.toString());
1159
                            // close the connection 
1160
                            close_connections(false);
1161
                        }      
1162
 
1163
                // sleep a bit to  get someting more done
1164
                //              sleep(5); //50
1165
 
1166
            } // while
1167
        //      log("Leaving Communicator thread");
1168
    } // run()
1169
}