Subversion Repositories Projects

Rev

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