Subversion Repositories Projects

Rev

Rev 449 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
391 Brean 1
#include <Parser.h>
2
 
449 Brean 3
/**
4
 * create a frame that can be send to the MK using the
5
 * connection class.
6
 * see http://www.mikrokopter.com/ucwiki/en/SerialProtocol
7
 * how the protocol is encoded and
8
 * see http://www.mikrokopter.com/ucwiki/en/SerialCommands
9
 * to look at the possible commands that are already coded
10
 * in data
11
 */
12
void Parser::create_frame(char cmd, int address, char * data, unsigned int length) {
450 Brean 13
    //if # is cmd we do not touch anything, because
14
    // the command is already encoded in data
15
    if (cmd != '#') {
16
        /*
17
        //calculate buffer length
18
        //(4 Bytes for 1-byte '#', 1-byte address, and 2-byte crc)
19
        //(the rest for the data length - see encode how this is calculated)
20
        int buff_len = 4+(length/3 + (length%3==0?0:1) )*4;
449 Brean 21
 
450 Brean 22
        //allociate memory for the data we want to send
23
        char * send_data = (char *)malloc(buf_len);
24
        */
25
        Parser::encode64(data, length);
26
        char send_data[150];
27
        send_data[0]='#';
28
        send_data[1]=(char)address+'a';
29
        send_data[2]=cmd;
30
        for (int i = 0; i < length; i++)
31
            send_data[i+3] = data[i];
32
        add_CRC(send_data, length+3);
33
        data = send_data;
34
    }
449 Brean 35
}
36
 
37
 
38
/**
39
 * Base64 Decoder
40
 * see Parser.h for details about sRxData
41
 * data = data that will be decoded
42
 * len = length of data
43
 * ptrOut = pointer to decoded data
44
 * offset = offset in data
45
 */
46
int Parser::decode64(char * data, int len, unsigned char *ptrOut, int offset)
391 Brean 47
{
48
    unsigned char a,b,c,d;
49
    unsigned char ptr = 0;
50
    unsigned char x,y,z;
51
 
52
    int decLen = 0;
449 Brean 53
/*
54
    //FIXME: dies wieder einklammern!
55
    if (data[ptrIn] == 0) {
56
        return -1;
396 Brean 57
        //TODO: catch error to show that something went wrong during the decode process
58
        //throw "Nothing received";
391 Brean 59
    }
449 Brean 60
*/
61
    //decode data
62
    while(len) {
63
        a = data[offset++] - '=';
64
        b = data[offset++] - '=';
65
        c = data[offset++] - '=';
66
        d = data[offset++] - '=';
391 Brean 67
 
449 Brean 68
        //if(offset > max - 2) break;
391 Brean 69
 
70
        x = (a << 2) | (b >> 4);
71
        y = ((b & 0x0f) << 4) | (c >> 2);
72
        z = ((c & 0x03) << 6) | d;
73
 
74
        if(len--) ptrOut[ptr++] = x; else break;
75
        if(len--) ptrOut[ptr++] = y; else break;
76
        if(len--) ptrOut[ptr++] = z; else break;
77
    }
449 Brean 78
    //decoded data
79
    unsigned char * decData;
391 Brean 80
    for (int a=0; a<ptr; a++) {
449 Brean 81
        if (len) {
82
            decData[decLen] = ptrOut[a];
83
            decLen++;
84
        } else {
391 Brean 85
            int b1, b2, b3;
86
 
87
            b1 = ptrOut[a++];
88
            b2 = ptrOut[a];
89
 
90
            b3 = (b2 << 8) | b1;
91
 
92
            if (b3 > 32767)
93
                b3 = b3 - 65536;
94
 
449 Brean 95
            decData[decLen] = b3;
396 Brean 96
            decLen++;
391 Brean 97
        }
98
    }
449 Brean 99
    ptrOut = decData;
100
    return decLen;
391 Brean 101
}
102
 
449 Brean 103
/**
104
 * base64 encoder
105
 */
106
void Parser::encode64(char data[150],unsigned int length)
391 Brean 107
{
108
    unsigned int pt = 0;
109
    unsigned char a,b,c;
110
    unsigned char ptr = 0;
111
 
112
    char tx_buff[150];
113
 
396 Brean 114
    while(length > 0)
391 Brean 115
    {
396 Brean 116
        if(length) { a = data[ptr++]; length--;} else a = 0;
117
        if(length) { b = data[ptr++]; length--;} else b = 0;
118
        if(length) { c = data[ptr++]; length--;} else c = 0;
391 Brean 119
 
120
        tx_buff[pt++] = '=' + (a >> 2);
121
        tx_buff[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
122
        tx_buff[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
123
        tx_buff[pt++] = '=' + ( c & 0x3f);
124
    }
125
    tx_buff[pt] = 0;
126
 
449 Brean 127
    //move pointer of tx_buff to data
128
    data = tx_buff;
391 Brean 129
}
130
 
131
// Datensatz nach 8bit Integer
450 Brean 132
int Parser::dataToChar(char *data , int start, bool is_signed) {
391 Brean 133
    int out = (data[start]);
134
 
135
    if ((out > 128) && (is_signed))
136
      out = out - 256;
137
 
138
    return out;
139
}
140
 
449 Brean 141
/**
142
 * received char to 8 bit integer
143
 */
391 Brean 144
int Parser::charToData(int data) {
145
    if (data < 0)
146
        return data + 256;
147
    return data;
148
}
149
 
449 Brean 150
/**
151
 * convert data to 16bit Integer
152
 */
450 Brean 153
int Parser::dataToInt(char *Data , int Start, bool is_signed)
391 Brean 154
{
155
    int Out = (Data[Start+1]<<8) | (Data[Start+0]);
156
 
157
    if ((Out > 32767) && (is_signed))
158
      Out = Out - 65536;
159
 
160
    return Out;
161
 
162
}
163
 
449 Brean 164
/**
165
 * convert data to 32bit Long
166
 */
450 Brean 167
long Parser::dataToLong(char *Data , int Start, bool is_signed)
391 Brean 168
{
169
    long Out = (Data[Start+3]<<24) | (Data[Start+2]<<16) | (Data[Start+1]<<8) | (Data[Start+0]);
170
 
171
    if ((Out > 32767) && (is_signed))
172
      Out = Out;
173
 
174
    return Out;
175
}
176
 
450 Brean 177
std::string Parser::dataToString(char * data, int start, int end)
178
{
179
    char tmp[MAX_DATA_SIZE];
180
    for (int i = start; i < end; i++)
181
        tmp[i-start] = data[i];
182
    return std::string(tmp);
183
}
184
 
391 Brean 185
float Parser::getFloat(long value, int count)
186
{
396 Brean 187
    long num = pow(10, count);
391 Brean 188
 
189
    float temp = value;
190
 
396 Brean 191
    return temp / num;
391 Brean 192
}
193
 
449 Brean 194
/**
195
 * check CRC
196
 */
197
bool Parser::check_CRC(char * rx, int length)
391 Brean 198
{
199
    int CRC = 0;
200
 
449 Brean 201
    if (rx[1] == 127)
391 Brean 202
    {
449 Brean 203
        rx[1] = 0;
391 Brean 204
    }
205
 
206
    for(int i=0; i < length-2; i++)
207
    {
449 Brean 208
            CRC+=rx[i];
391 Brean 209
    }
210
 
211
    CRC = CRC % 4096;
212
 
449 Brean 213
    if(rx[length - 2] != ('=' + (CRC / 64)))
391 Brean 214
    {
215
        return false;
216
    }
217
 
449 Brean 218
    if(rx[length - 1] != ('=' + CRC % 64))
391 Brean 219
    {
220
        return false;
221
    }
222
 
223
    return true;
224
}
225
 
449 Brean 226
/**
227
 * create CRC and add it to tx
228
 */
229
void Parser::add_CRC(char * tx, int length)
391 Brean 230
{
231
    unsigned int tmpCRC = 0;
232
 
233
    for(int i = 0; i < length; i++)
234
    {
449 Brean 235
        tmpCRC += tx[i];
391 Brean 236
    }
237
 
238
    tmpCRC %= 4096;
239
 
450 Brean 240
    tx[length] = '=' + tmpCRC / 64;
241
    tx[length+1] = '=' + tmpCRC % 64;
242
    tx[length+2] = '\0';
391 Brean 243
}
244