Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
969 runge 1
/***************************************************************************
2
 *   Copyright (C) November 28, 2008 by Mattias Runge                             *
3
 *   mattias@runge.se                                                      *
4
 *   canidtranslator.cpp                                            *
5
 *                                                                         *
6
 *   This program is free software; you can redistribute it and/or modify  *
7
 *   it under the terms of the GNU General Public License as published by  *
8
 *   the Free Software Foundation; either version 2 of the License, or     *
9
 *   (at your option) any later version.                                   *
10
 *                                                                         *
11
 *   This program is distributed in the hope that it will be useful,       *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU General Public License for more details.                          *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU General Public License     *
17
 *   along with this program; if not, write to the                         *
18
 *   Free Software Foundation, Inc.,                                       *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20
 ***************************************************************************/
21
 
22
#include "canidtranslator.h"
23
 
24
CanIdTranslator* CanIdTranslator::myInstance = NULL;
25
 
26
CanIdTranslator& CanIdTranslator::getInstance()
27
{
28
    if (myInstance == NULL)
29
    {
30
        myInstance = new CanIdTranslator();
31
    }
32
 
33
    return *myInstance;
34
}
35
 
36
void CanIdTranslator::deleteInstance()
37
{
38
    delete myInstance;
39
    myInstance = NULL;
40
}
41
 
42
CanIdTranslator::CanIdTranslator()
43
{
44
    SyslogStream &slog = SyslogStream::getInstance();
45
 
46
    string filename = Settings::get("CanIdXMLFile");
47
 
48
    xmlNode.load(filename.c_str());
49
 
976 runge 50
    slog << "Loading definitions from " + filename + ".\n";
969 runge 51
}
52
 
53
string CanIdTranslator::lookupClassName(int classId)
54
{
55
    XmlNode classesNode = xmlNode.findChild("classes");
56
    vector<XmlNode> classNodes = classesNode.getChildren();
57
 
58
    for (int n = 0; n < classNodes.size(); n++)
59
    {
60
        map<string, string> attributes = classNodes[n].getAttributes();
61
 
62
        if (stoi(attributes["id"]) == classId)
63
        {
64
            return attributes["name"];
65
        }
66
    }
67
 
68
    return "";
69
}
70
 
71
int CanIdTranslator::resolveClassId(string className)
72
{
73
    XmlNode classesNode = xmlNode.findChild("classes");
74
    vector<XmlNode> classNodes = classesNode.getChildren();
75
 
76
    for (int n = 0; n < classNodes.size(); n++)
77
    {
78
        map<string, string> attributes = classNodes[n].getAttributes();
79
 
80
        if (attributes["name"].compare(className) == 0)
81
        {
82
            return stoi(attributes["id"]);
83
        }
84
    }
85
 
86
    return -1;
87
}
88
 
89
string CanIdTranslator::lookupCommandName(int commandId, string moduleName)
90
{
91
    XmlNode commandsNode = xmlNode.findChild("commands");
92
    vector<XmlNode> commandNodes = commandsNode.getChildren();
93
 
94
    for (int n = 0; n < commandNodes.size(); n++)
95
    {
96
        map<string, string> attributes = commandNodes[n].getAttributes();
97
 
981 runge 98
        if (commandId >= 128)
969 runge 99
        {
100
            if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
101
            {
102
                return attributes["name"];
103
            }
104
        }
105
        else if (stoi(attributes["id"]) == commandId)
106
        {
107
            return attributes["name"];
108
        }
109
    }
110
 
111
    return "";
112
}
113
 
114
int CanIdTranslator::resolveCommandId(string commandName, string moduleName)
115
{
116
    XmlNode commandsNode = xmlNode.findChild("commands");
117
    vector<XmlNode> commandNodes = commandsNode.getChildren();
118
 
119
    for (int n = 0; n < commandNodes.size(); n++)
120
    {
121
        map<string, string> attributes = commandNodes[n].getAttributes();
122
 
123
        if (attributes["name"].compare(commandName) == 0)
124
        {
125
            int commandId = stoi(attributes["id"]);
126
 
981 runge 127
            if (commandId >= 128)
969 runge 128
            {
129
                if (attributes["module"] == moduleName)
130
                {
131
                    return commandId;
132
                }
133
            }
134
            else
135
            {
136
                return commandId;
137
            }
138
        }
139
    }
140
 
141
    return -1;
142
}
143
 
144
string CanIdTranslator::getDefineId(string name, string group)
145
{
146
    XmlNode definesNode = xmlNode.findChild("defines");
147
    vector<XmlNode> defineNodes = definesNode.getChildren();
148
 
149
    for (int n = 0; n < defineNodes.size(); n++)
150
    {
151
        map<string, string> attributes = defineNodes[n].getAttributes();
152
 
153
        if (attributes["group"] == group && attributes["name"] == name)
154
        {
155
            return attributes["id"];
156
        }
157
    }
158
 
159
    return "";
160
}
161
 
162
string CanIdTranslator::lookupDirectionFlag(int directionFlag)
163
{
164
    XmlNode definesNode = xmlNode.findChild("defines");
165
    vector<XmlNode> defineNodes = definesNode.getChildren();
166
 
167
    for (int n = 0; n < defineNodes.size(); n++)
168
    {
169
        map<string, string> attributes = defineNodes[n].getAttributes();
170
 
171
        if (attributes["group"].compare("DirectionFlag") == 0 && stoi(attributes["id"]) == directionFlag)
172
        {
173
            return attributes["name"];
174
        }
175
    }
176
 
177
    return "";
178
}
179
 
180
int CanIdTranslator::resolveDirectionFlag(string directionName)
181
{
182
    XmlNode definesNode = xmlNode.findChild("defines");
183
    vector<XmlNode> defineNodes = definesNode.getChildren();
184
 
185
    for (int n = 0; n < defineNodes.size(); n++)
186
    {
187
        map<string, string> attributes = defineNodes[n].getAttributes();
188
 
189
        if (attributes["group"].compare("DirectionFlag") == 0 && attributes["name"].compare(directionName) == 0)
190
        {
191
            return stoi(attributes["id"]);
192
        }
193
    }
194
 
195
    return -1;
196
}
197
 
198
string CanIdTranslator::lookupModuleName(int moduleId)
199
{
200
    XmlNode modulesNode = xmlNode.findChild("modules");
201
    vector<XmlNode> moduleNodes = modulesNode.getChildren();
202
 
203
    for (int n = 0; n < moduleNodes.size(); n++)
204
    {
205
        map<string, string> attributes = moduleNodes[n].getAttributes();
206
 
207
        if (stoi(attributes["id"]) == moduleId)
208
        {
209
            return attributes["name"];
210
        }
211
    }
212
 
213
    return "";
214
}
215
 
216
int CanIdTranslator::resolveModuleId(string moduleName)
217
{
218
    XmlNode modulesNode = xmlNode.findChild("modules");
219
    vector<XmlNode> moduleNodes = modulesNode.getChildren();
220
 
221
    for (int n = 0; n < moduleNodes.size(); n++)
222
    {
223
        map<string, string> attributes = moduleNodes[n].getAttributes();
224
 
225
        if (attributes["name"].compare(moduleName) == 0)
226
        {
227
            return stoi(attributes["id"]);
228
        }
229
    }
230
 
231
    return -1;
232
}
233
 
234
string CanIdTranslator::translateDataToHex(int commandId, string moduleName, map<string, CanVariable> data)
235
{
236
    XmlNode commandsNode = xmlNode.findChild("commands");
237
    vector<XmlNode> commandNodes = commandsNode.getChildren();
238
 
239
    map<string, CanVariable> sortedData;
240
 
241
    for (int n = 0; n < commandNodes.size(); n++)
242
    {
243
        map<string, string> attributes = commandNodes[n].getAttributes();
244
 
245
        bool correct = false;
246
 
981 runge 247
        if (commandId >= 128)
969 runge 248
        {
249
            if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
250
            {
251
                correct = true;
252
            }
253
        }
254
        else if (stoi(attributes["id"]) == commandId)
255
        {
256
            correct = true;
257
        }
258
 
259
        if (correct)
260
        {
261
            XmlNode varablesNode = commandNodes[n].findChild("variables");
262
 
263
            vector<XmlNode> variableNodes = varablesNode.getChildren();
264
 
265
            for (int c = 0; c < variableNodes.size(); c++)
266
            {
267
                map<string, string> attributes = variableNodes[c].getAttributes();
268
 
269
                if (data.find(attributes["name"]) != data.end())
270
                {
271
                    int bitStart = stoi(attributes["start_bit"]);///FIXME: This is not a good way
272
                    int bitLength = stoi(attributes["bit_length"]);
273
 
274
                    sortedData[attributes["name"]].setType(attributes["type"]);
275
                    sortedData[attributes["name"]].setUnit(attributes["unit"]);
276
                    sortedData[attributes["name"]].setBitLength(bitLength);
277
                    sortedData[attributes["name"]].setBitLength(bitLength);
278
                    sortedData[attributes["name"]].setStartBit(bitStart);
279
                    sortedData[attributes["name"]].setName(attributes["name"]);
280
                    sortedData[attributes["name"]].setValue(data[attributes["name"]].getValue());
281
                }
282
            }
283
        }
284
    }
285
 
286
    string bin = "0000000000000000000000000000000000000000000000000000000000000000";
287
    int heighestBit = 0;
288
 
289
    map<string, CanVariable>::iterator iter;
290
 
291
    for (iter = sortedData.begin(); iter != sortedData.end(); iter++)///FIXME: We should check order and length
292
    {
293
        if (iter->second.getType() == "uint")
294
        {
295
            if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
296
                heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
297
 
298
            //cout << iter->first << ":" <<  stoi(iter->second.getValue()) << endl;
981 runge 299
            unsigned int a = stoi(iter->second.getValue());
969 runge 300
 
301
            bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), uint2bin(a, iter->second.getBitLength()));
302
        }
303
        else if (iter->second.getType() == "float")
304
        {
305
            if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
306
                heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
307
 
308
            bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), float2bin(stof(iter->second.getValue()), iter->second.getBitLength()));
309
        }
310
        else if (iter->second.getType() == "ascii")
311
        {
312
            //cout << iter->second.getValue() << endl;
313
            for (int n = 0; n < iter->second.getValue().length(); n++)
314
            {
315
                if (iter->second.getStartBit()+n*8 + 8 > heighestBit)
316
                    heighestBit = iter->second.getStartBit()+n*8 + 8;
317
 
318
                //cout << iter->second.getValue()[n] << ":" << (unsigned int)iter->second.getValue()[n] << endl;
319
                bin.replace(iter->second.getStartBit()+n*8, 8, uint2bin((unsigned int)iter->second.getValue()[n], 8));
320
            }
321
        }
981 runge 322
        else if (iter->second.getType() == "hexstring")
323
        {
324
            for (int n = 0; n < iter->second.getValue().length(); n++)
325
            {
326
                if (iter->second.getStartBit()+n*4 + 4 > heighestBit)
327
                    heighestBit = iter->second.getStartBit()+n*4 + 4;
328
 
329
                string character;
330
                character += iter->second.getValue()[n];
331
 
332
                bin.replace(iter->second.getStartBit()+n*4, 4, hex2bin(character));
333
            }
334
        }
969 runge 335
    }
336
 
337
    bin = bin.substr(0, heighestBit);
338
 
339
    //cout << bin2hex(bin) << endl;
340
 
341
    return bin2hex(bin);
342
}
343
 
344
map<string, CanVariable> CanIdTranslator::translateData(int commandId, string moduleName, string dataHex)
345
{
346
    map<string, CanVariable> variables;
347
    XmlNode commandsNode = xmlNode.findChild("commands");
348
    vector<XmlNode> commandNodes = commandsNode.getChildren();
349
 
350
    string dataBin = hex2bin(dataHex);
351
    //string dataString = "{";
352
 
353
    for (int n = 0; n < commandNodes.size(); n++)
354
    {
355
        map<string, string> attributes = commandNodes[n].getAttributes();
356
 
357
        bool correct = false;
358
 
981 runge 359
        if (commandId >= 128)
969 runge 360
        {
361
            if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
362
            {
363
                correct = true;
364
            }
365
        }
366
        else if (stoi(attributes["id"]) == commandId)
367
        {
368
            correct = true;
369
        }
370
 
371
        if (correct)
372
        {
373
            XmlNode varablesNode = commandNodes[n].findChild("variables");
374
 
375
            vector<XmlNode> variableNodes = varablesNode.getChildren();
376
 
377
            for (int c = 0; c < variableNodes.size(); c++)
378
            {
379
                map<string, string> attributes = variableNodes[c].getAttributes();
380
 
381
                int bitStart = stoi(attributes["start_bit"]);
382
                int bitLength = stoi(attributes["bit_length"]);
383
 
384
                string bits = dataBin.substr(bitStart, bitLength);
385
 
386
                CanVariable variable;
387
 
388
                variable.setName(attributes["name"]);
389
                variable.setType(attributes["type"]);
390
                variable.setUnit(attributes["unit"]);
391
                variable.setBitLength(bitLength);
392
 
393
                //dataString += " " + attributes["name"] + " : { value : ";
394
                //dataString += attributes["name"] + "=";
395
                //dataString += attributes["name"] + ":" + attributes["type"] + ":" + attributes["bit_length"] + "=\"";
396
 
397
                if (attributes["type"] == "uint")
398
                {
399
                    variable.setValue(itos(bin2uint(bits)));
400
                    //dataString += itos(bin2uint(bits));
401
                }
402
                else if (attributes["type"] == "float")
403
                {
404
                    variable.setValue(ftos(bin2float(bits)));
405
                    //dataString += ftos(bin2float(bits));
406
                }
407
                else if (attributes["type"] == "ascii")
408
                {
409
                    string str;
410
                    //dataString += "'";
411
 
412
                    for (int k = 0; k < bits.length(); k += 8)
413
                    {
414
                        str += (char)bin2uint(bits.substr(k, 8));
415
                        //dataString += (char)bin2uint(bits.substr(k, 4));
416
                    }
417
 
418
                    variable.setValue(str);
419
                    //cout << "Parsed ascii: " << str << "\n";
420
                    //dataString += "'";
421
                }
981 runge 422
                else if (attributes["type"] == "hexstring")
423
                {
424
                    string str;
969 runge 425
 
981 runge 426
                    for (int k = 0; k < bits.length(); k += 4)
427
                    {
428
                        str += bin2hex(bits.substr(k, 4));
429
                        //dataString += (char)bin2uint(bits.substr(k, 4));
430
                    }
431
 
432
                    variable.setValue(str);
433
                }
434
 
969 runge 435
                variables[attributes["name"]] = variable;
436
 
437
                //dataString += ", type : '" + attributes["type"] + "', bits : " + attributes["bit_length"] + ", unit : '" + attributes["unit"] + "' },";
438
 
439
                //dataString += ",";
440
                //dataString += "\",";
441
            }
442
 
443
            //dataString = trim(dataString, ',');
444
 
445
            //dataString += " }";
446
 
447
            //return dataString;
448
 
449
 
450
            return variables;
451
        }
452
    }
453
 
454
    //return dataString + " ]";
455
    return variables;
456
}
457
 
458
map<string, CanVariable> CanIdTranslator::translateHeartbeatData(string dataHex)
459
{
460
    map<string, CanVariable> variables;
461
 
462
    string dataBin = hex2bin(dataHex);
463
    string bits = dataBin.substr(0, 32);
464
 
465
    CanVariable canVariable("HardwareId", itos(bin2uint(bits)), "uint", "");
466
    canVariable.setBitLength(32);
467
 
468
    variables["HardwareId"] = canVariable;
469
 
470
    return variables;
471
 
472
    //return "{ HardwareId : { value : " + itos(bin2uint(bits)) + ", type : 'uint', bits : 32, unit : '' }";
473
    //return "HardwareId:uint:32=\"" + itos(bin2uint(bits)) + "\"";
474
}