Subversion Repositories Projects

Rev

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