Subversion Repositories FlightCtrl

Rev

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

Rev Author Line No. Line
164 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
 * Project-Start: 9/2007                                                                                                          *
7
 * Version:       0.07                                                                                                            *            
8
 * Mailto:        ligi@smart4mobile.de                                                                                            *
9
 * Licence:       Creative Commons / Non Commercial                                                                               *
10
 * Big Up:        Holger&Ingo                                                                                                     *
11
 * ChangeLog:                                                                                                                     *
12
 *              0.01 - initial Version ( initialize connection / main Thread with reading data from MK)                           *
13
 *              0.02 - reconnect after connection loss ( e.g. switching on/off )                                                  *
14
 *              0.03 - added send_command ( with CRC )                                                                            *
15
 *              0.04 - added decode64 to decode 'pseudo' BASE64                                                                   *
16
 *              0.05 - added get_version                                                                                          *
17
 *              0.06 - added parsing of DebugData                                                                                 *
18
 *              0.07 - Code-(Doc&&Cleanup) && initial svn commit                                                                  *                  
19
 *                                                                                                                                *
20
 *********************************************************************************************************************************/
21
 
22
import javax.microedition.io.*;
23
import java.io.*;
24
 
25
public class MKCommunicator
26
   implements Runnable
27
{
28
    /***************** Section: public Attributes **********************************************/
29
    public boolean connected=false; // flag for the connection state
30
    public boolean fatal=false; // flag which is set when an error is so fatal that reconnecting won't be tried - e.g. unknown version number.
31
 
32
 
33
    public String mk_url=""; // buffer the url which is given in the constuctor for reconnectin purposes
34
 
35
 
36
 
37
    // version Info from Flight Control
38
    public int version_major=-1;
39
    public int version_minor=-1;
40
    public int version_compatible=-1;
41
 
42
 
43
 
44
 
45
    /****************** Section: private Attributes **********************************************/
46
    private javax.microedition.io.StreamConnection connection;
47
    private java.io.InputStream reader;    
48
    private java.io.OutputStream writer;    
49
 
50
 
51
    // temp - to be removed
52
    String p_msg="--";
53
    public String msg="BT_INIT";
54
 
55
    int data_count=0;
56
 
57
 
58
    /******************  Section: public Methods ************************************************/
59
    public MKCommunicator(String url)     // Constructor with URL string e.g. "btspp://XXXXXXXXXXXX:1" - the X-Part is the MAC-Adress of the Bluetooth-Device connected to the Fligth-Control
60
    {
61
        mk_url=url; // remember URL for connecting / reconnecting later
62
        new Thread( this ).start(); // fire up main Thread 
63
    }
64
 
65
 
66
    /******************  Section: private Methods ************************************************/
67
    private void connect()
68
    {
69
        try{
70
                connection = (StreamConnection) Connector.open(mk_url, Connector.READ_WRITE);
71
                reader=connection.openInputStream();
72
                writer=connection.openOutputStream();
73
                connected=true; // if we get here everything seems to be OK
74
           }
75
        catch (Exception ex)
76
            {
77
                // TODO difference fatal errors from those which will lead to reconnection
78
                msg="Problem connecting" + "\n" + ex;
79
            }  
80
 
81
        get_version();
82
    }
83
 
84
 
85
 
86
    public int[] Decode64(int[] in_arr, int offset,int len)
87
    {
88
        int ptrIn=offset;      
89
        int a,b,c,d,x,y,z;
90
        int ptr=0;
91
 
92
        int[] out_arr=new int[len];
93
 
94
        while(len!=0)
95
            {
96
                a = in_arr[ptrIn++] - '=';
97
                b = in_arr[ptrIn++] - '=';
98
                c = in_arr[ptrIn++] - '=';
99
                d = in_arr[ptrIn++] - '=';
100
                //if(ptrIn > max - 2) break;     // nicht mehr Daten verarbeiten, als empfangen wurden
101
 
102
                x = (a << 2) | (b >> 4);
103
                y = ((b & 0x0f) << 4) | (c >> 2);
104
                z = ((c & 0x03) << 6) | d;
105
 
106
                if((len--)!=0) out_arr[ptr++] = x; else break;
107
                if((len--)!=0) out_arr[ptr++] = y; else break;
108
                if((len--)!=0) out_arr[ptr++] = z; else break;
109
            }
110
 
111
        return out_arr;
112
 
113
    }
114
 
115
 
116
    // send a version Request to the FC - the reply to this request will be processed in process_data when it arrives
117
    public void get_version()
118
    {
119
        send_command(0,'v',new int[0]);
120
    }
121
 
122
    // send command to FC ( add crc and pack into pseudo Base64
123
    public void send_command(int modul,char cmd,int[] params)
124
    {
125
        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
126
        send_buff[0]='#';
127
        send_buff[1]=(char)modul;
128
        send_buff[2]=cmd;
129
 
130
        try
131
            {
132
                int tmp_crc=0;
133
                for ( int tmp_i=0; tmp_i<send_buff.length;tmp_i++)
134
                    {
135
                        tmp_crc+=(int)send_buff[tmp_i];
136
                        writer.write(send_buff[tmp_i]);
137
                    }
138
                tmp_crc%=4096;
139
                writer.write( (char)(tmp_crc/64 + '='));
140
                writer.write( (char)(tmp_crc%64 + '='));
141
                writer.write('\r');
142
                writer.flush();
143
            }
144
        catch (Exception e)
145
            { // problem sending data to FC
146
            }
147
 
148
    }
149
 
150
    MKDebugData debug_data;
151
    public void process_data(int[] data,int len)
152
    {
153
        int[] decoded_data;
154
 
155
        switch((char)data[2])
156
            {
157
 
158
            case 'D': // debug Data
159
                decoded_data=Decode64(data,3,50);
160
                debug_data=new MKDebugData(decoded_data);
161
                msg="Got Debug Data s:" + debug_data.sekunden + "zy:"+debug_data.zyklen + "ze:" + debug_data.zeit + connected + ">" + data_count;
162
                for (int ff=0;ff<8;ff++)
163
                    msg+="\n  d:" + (ff*2+1) + " " + debug_data.analog[ff*2] + " d2:" + (ff*2+2) + " "  + debug_data.analog[ff*2+1] ;
164
 
165
                break;
166
 
167
            case 'V': // Version Info
168
                decoded_data=Decode64(data,3,6);
169
                version_major=decoded_data[0];
170
                version_minor=decoded_data[1];
171
                version_compatible=decoded_data[2];
172
 
173
                break;
174
 
175
            default:
176
                break;
177
 
178
            }
179
 
180
 
181
        msg+=p_msg;
182
        msg+="OK";
183
        data_count++;
184
 
185
    }
186
 
187
    // Thread to recieve data from Connection
188
    public void run()
189
    {
190
        int[] data_set=new int[150];
191
        int input;
192
        int pos=0;
193
        msg+="!!run started!!";
194
        while(true)
195
            {
196
            if (!connected)
197
                connect();
198
            else
199
                try{
200
                    pos=0;
201
                    input=0;
202
                    // recieve data-set
203
                    while ((input != 13)) // &&(input!=-1))
204
                       {
205
                           input = reader.read() ;
206
                           if (input==-1) throw new Exception("test");
207
                           data_set[pos]=input;
208
                           pos++;
209
 
210
                       }
211
                    process_data(data_set,pos);
212
 
213
                   }
214
        catch (Exception ex)
215
            {
216
                msg="Problem reading from MK";
217
                // close the connection 
218
                try{ reader.close(); connection.close(); }
219
                catch (Exception inner_ex) { }
220
                connected=false;
221
            }  
222
 
223
            // sleep a bit to get someting more done
224
            try { Thread.sleep(50); }
225
            catch (Exception e)  {   }
226
 
227
            } // while
228
 
229
 
230
    } // run()
231
 
232
 
233
}