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
 
985 runge 48
    if (file_exists(filename))
49
    {
50
        xmlNode.load(filename.c_str());
969 runge 51
 
985 runge 52
        slog << "Loading definitions from " + filename + ".\n";
53
    }
54
    else
55
    {
56
        slog << "CanIdXMLFile is not defined in the config file, this will probably not work at all.\n";
57
    }
969 runge 58
}
59
 
60
string CanIdTranslator::lookupClassName(int classId)
61
{
62
    XmlNode classesNode = xmlNode.findChild("classes");
63
    vector<XmlNode> classNodes = classesNode.getChildren();
64
 
65
    for (int n = 0; n < classNodes.size(); n++)
66
    {
67
        map<string, string> attributes = classNodes[n].getAttributes();
68
 
69
        if (stoi(attributes["id"]) == classId)
70
        {
71
            return attributes["name"];
72
        }
73
    }
74
 
75
    return "";
76
}
77
 
78
int CanIdTranslator::resolveClassId(string className)
79
{
80
    XmlNode classesNode = xmlNode.findChild("classes");
81
    vector<XmlNode> classNodes = classesNode.getChildren();
82
 
83
    for (int n = 0; n < classNodes.size(); n++)
84
    {
85
        map<string, string> attributes = classNodes[n].getAttributes();
86
 
87
        if (attributes["name"].compare(className) == 0)
88
        {
89
            return stoi(attributes["id"]);
90
        }
91
    }
92
 
93
    return -1;
94
}
95
 
96
string CanIdTranslator::lookupCommandName(int commandId, string moduleName)
97
{
98
    XmlNode commandsNode = xmlNode.findChild("commands");
99
    vector<XmlNode> commandNodes = commandsNode.getChildren();
100
 
101
    for (int n = 0; n < commandNodes.size(); n++)
102
    {
103
        map<string, string> attributes = commandNodes[n].getAttributes();
104
 
981 runge 105
        if (commandId >= 128)
969 runge 106
        {
107
            if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
108
            {
109
                return attributes["name"];
110
            }
111
        }
112
        else if (stoi(attributes["id"]) == commandId)
113
        {
114
            return attributes["name"];
115
        }
116
    }
117
 
118
    return "";
119
}
120
 
121
int CanIdTranslator::resolveCommandId(string commandName, string moduleName)
122
{
123
    XmlNode commandsNode = xmlNode.findChild("commands");
124
    vector<XmlNode> commandNodes = commandsNode.getChildren();
125
 
126
    for (int n = 0; n < commandNodes.size(); n++)
127
    {
128
        map<string, string> attributes = commandNodes[n].getAttributes();
129
 
130
        if (attributes["name"].compare(commandName) == 0)
131
        {
132
            int commandId = stoi(attributes["id"]);
133
 
981 runge 134
            if (commandId >= 128)
969 runge 135
            {
136
                if (attributes["module"] == moduleName)
137
                {
138
                    return commandId;
139
                }
140
            }
141
            else
142
            {
143
                return commandId;
144
            }
145
        }
146
    }
147
 
148
    return -1;
149
}
150
 
986 runge 151
string CanIdTranslator::lookupNMTCommandName(int commandId)
152
{
153
    XmlNode commandsNode = xmlNode.findChild("nmt_messages");
154
    vector<XmlNode> commandNodes = commandsNode.getChildren();
155
 
156
    for (int n = 0; n < commandNodes.size(); n++)
157
    {
158
        map<string, string> attributes = commandNodes[n].getAttributes();
159
 
160
        if (stoi(attributes["id"]) == commandId)
161
        {
162
            return attributes["name"];
163
        }
164
    }
165
 
166
    return "";
167
}
168
 
169
int CanIdTranslator::resolveNMTCommandId(string commandName)
170
{
171
    XmlNode commandsNode = xmlNode.findChild("nmt_messages");
172
    vector<XmlNode> commandNodes = commandsNode.getChildren();
173
 
174
    for (int n = 0; n < commandNodes.size(); n++)
175
    {
176
        map<string, string> attributes = commandNodes[n].getAttributes();
177
 
178
        if (attributes["name"].compare(commandName) == 0)
179
        {
180
            return stoi(attributes["id"]);
181
        }
182
    }
183
 
184
    return -1;
185
}
186
 
969 runge 187
string CanIdTranslator::getDefineId(string name, string group)
188
{
189
    XmlNode definesNode = xmlNode.findChild("defines");
190
    vector<XmlNode> defineNodes = definesNode.getChildren();
191
 
192
    for (int n = 0; n < defineNodes.size(); n++)
193
    {
194
        map<string, string> attributes = defineNodes[n].getAttributes();
195
 
196
        if (attributes["group"] == group && attributes["name"] == name)
197
        {
198
            return attributes["id"];
199
        }
200
    }
201
 
202
    return "";
203
}
204
 
205
string CanIdTranslator::lookupDirectionFlag(int directionFlag)
206
{
207
    XmlNode definesNode = xmlNode.findChild("defines");
208
    vector<XmlNode> defineNodes = definesNode.getChildren();
209
 
210
    for (int n = 0; n < defineNodes.size(); n++)
211
    {
212
        map<string, string> attributes = defineNodes[n].getAttributes();
213
 
214
        if (attributes["group"].compare("DirectionFlag") == 0 && stoi(attributes["id"]) == directionFlag)
215
        {
216
            return attributes["name"];
217
        }
218
    }
219
 
220
    return "";
221
}
222
 
223
int CanIdTranslator::resolveDirectionFlag(string directionName)
224
{
225
    XmlNode definesNode = xmlNode.findChild("defines");
226
    vector<XmlNode> defineNodes = definesNode.getChildren();
227
 
228
    for (int n = 0; n < defineNodes.size(); n++)
229
    {
230
        map<string, string> attributes = defineNodes[n].getAttributes();
231
 
232
        if (attributes["group"].compare("DirectionFlag") == 0 && attributes["name"].compare(directionName) == 0)
233
        {
234
            return stoi(attributes["id"]);
235
        }
236
    }
237
 
238
    return -1;
239
}
240
 
241
string CanIdTranslator::lookupModuleName(int moduleId)
242
{
243
    XmlNode modulesNode = xmlNode.findChild("modules");
244
    vector<XmlNode> moduleNodes = modulesNode.getChildren();
245
 
246
    for (int n = 0; n < moduleNodes.size(); n++)
247
    {
248
        map<string, string> attributes = moduleNodes[n].getAttributes();
249
 
250
        if (stoi(attributes["id"]) == moduleId)
251
        {
252
            return attributes["name"];
253
        }
254
    }
255
 
256
    return "";
257
}
258
 
259
int CanIdTranslator::resolveModuleId(string moduleName)
260
{
261
    XmlNode modulesNode = xmlNode.findChild("modules");
262
    vector<XmlNode> moduleNodes = modulesNode.getChildren();
263
 
264
    for (int n = 0; n < moduleNodes.size(); n++)
265
    {
266
        map<string, string> attributes = moduleNodes[n].getAttributes();
267
 
268
        if (attributes["name"].compare(moduleName) == 0)
269
        {
270
            return stoi(attributes["id"]);
271
        }
272
    }
273
 
274
    return -1;
275
}
276
 
277
string CanIdTranslator::translateDataToHex(int commandId, string moduleName, map<string, CanVariable> data)
278
{
279
    XmlNode commandsNode = xmlNode.findChild("commands");
280
    vector<XmlNode> commandNodes = commandsNode.getChildren();
281
 
282
    map<string, CanVariable> sortedData;
283
 
284
    for (int n = 0; n < commandNodes.size(); n++)
285
    {
286
        map<string, string> attributes = commandNodes[n].getAttributes();
287
 
288
        bool correct = false;
289
 
981 runge 290
        if (commandId >= 128)
969 runge 291
        {
292
            if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
293
            {
294
                correct = true;
295
            }
296
        }
297
        else if (stoi(attributes["id"]) == commandId)
298
        {
299
            correct = true;
300
        }
301
 
302
        if (correct)
303
        {
304
            XmlNode varablesNode = commandNodes[n].findChild("variables");
305
 
306
            vector<XmlNode> variableNodes = varablesNode.getChildren();
307
 
308
            for (int c = 0; c < variableNodes.size(); c++)
309
            {
310
                map<string, string> attributes = variableNodes[c].getAttributes();
311
 
312
                if (data.find(attributes["name"]) != data.end())
313
                {
314
                    int bitStart = stoi(attributes["start_bit"]);///FIXME: This is not a good way
315
                    int bitLength = stoi(attributes["bit_length"]);
316
 
317
                    sortedData[attributes["name"]].setType(attributes["type"]);
318
                    sortedData[attributes["name"]].setUnit(attributes["unit"]);
319
                    sortedData[attributes["name"]].setBitLength(bitLength);
320
                    sortedData[attributes["name"]].setBitLength(bitLength);
321
                    sortedData[attributes["name"]].setStartBit(bitStart);
322
                    sortedData[attributes["name"]].setName(attributes["name"]);
323
                    sortedData[attributes["name"]].setValue(data[attributes["name"]].getValue());
324
                }
325
            }
326
        }
327
    }
328
 
329
    string bin = "0000000000000000000000000000000000000000000000000000000000000000";
330
    int heighestBit = 0;
331
 
332
    map<string, CanVariable>::iterator iter;
333
 
334
    for (iter = sortedData.begin(); iter != sortedData.end(); iter++)///FIXME: We should check order and length
335
    {
336
        if (iter->second.getType() == "uint")
337
        {
338
            if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
339
                heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
340
 
341
            //cout << iter->first << ":" <<  stoi(iter->second.getValue()) << endl;
981 runge 342
            unsigned int a = stoi(iter->second.getValue());
969 runge 343
 
344
            bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), uint2bin(a, iter->second.getBitLength()));
345
        }
346
        else if (iter->second.getType() == "float")
347
        {
348
            if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
349
                heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
350
 
351
            bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), float2bin(stof(iter->second.getValue()), iter->second.getBitLength()));
352
        }
353
        else if (iter->second.getType() == "ascii")
354
        {
355
            //cout << iter->second.getValue() << endl;
356
            for (int n = 0; n < iter->second.getValue().length(); n++)
357
            {
358
                if (iter->second.getStartBit()+n*8 + 8 > heighestBit)
359
                    heighestBit = iter->second.getStartBit()+n*8 + 8;
360
 
361
                //cout << iter->second.getValue()[n] << ":" << (unsigned int)iter->second.getValue()[n] << endl;
362
                bin.replace(iter->second.getStartBit()+n*8, 8, uint2bin((unsigned int)iter->second.getValue()[n], 8));
363
            }
364
        }
981 runge 365
        else if (iter->second.getType() == "hexstring")
366
        {
367
            for (int n = 0; n < iter->second.getValue().length(); n++)
368
            {
369
                if (iter->second.getStartBit()+n*4 + 4 > heighestBit)
370
                    heighestBit = iter->second.getStartBit()+n*4 + 4;
371
 
372
                string character;
373
                character += iter->second.getValue()[n];
374
 
375
                bin.replace(iter->second.getStartBit()+n*4, 4, hex2bin(character));
376
            }
377
        }
969 runge 378
    }
379
 
380
    bin = bin.substr(0, heighestBit);
381
 
382
    //cout << bin2hex(bin) << endl;
383
 
384
    return bin2hex(bin);
385
}
386
 
387
map<string, CanVariable> CanIdTranslator::translateData(int commandId, string moduleName, string dataHex)
388
{
389
    map<string, CanVariable> variables;
390
    XmlNode commandsNode = xmlNode.findChild("commands");
391
    vector<XmlNode> commandNodes = commandsNode.getChildren();
392
 
393
    string dataBin = hex2bin(dataHex);
394
 
395
    for (int n = 0; n < commandNodes.size(); n++)
396
    {
397
        map<string, string> attributes = commandNodes[n].getAttributes();
398
 
399
        bool correct = false;
400
 
981 runge 401
        if (commandId >= 128)
969 runge 402
        {
403
            if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
404
            {
405
                correct = true;
406
            }
407
        }
408
        else if (stoi(attributes["id"]) == commandId)
409
        {
410
            correct = true;
411
        }
412
 
413
        if (correct)
414
        {
415
            XmlNode varablesNode = commandNodes[n].findChild("variables");
416
 
417
            vector<XmlNode> variableNodes = varablesNode.getChildren();
418
 
419
            for (int c = 0; c < variableNodes.size(); c++)
420
            {
421
                map<string, string> attributes = variableNodes[c].getAttributes();
422
 
423
                int bitStart = stoi(attributes["start_bit"]);
424
                int bitLength = stoi(attributes["bit_length"]);
425
 
426
                string bits = dataBin.substr(bitStart, bitLength);
427
 
428
                CanVariable variable;
429
 
430
                variable.setName(attributes["name"]);
431
                variable.setType(attributes["type"]);
432
                variable.setUnit(attributes["unit"]);
433
                variable.setBitLength(bitLength);
434
 
435
                if (attributes["type"] == "uint")
436
                {
437
                    variable.setValue(itos(bin2uint(bits)));
438
                }
439
                else if (attributes["type"] == "float")
440
                {
441
                    variable.setValue(ftos(bin2float(bits)));
442
                }
443
                else if (attributes["type"] == "ascii")
444
                {
445
                    string str;
446
 
447
                    for (int k = 0; k < bits.length(); k += 8)
448
                    {
449
                        str += (char)bin2uint(bits.substr(k, 8));
450
                    }
451
 
452
                    variable.setValue(str);
453
                }
981 runge 454
                else if (attributes["type"] == "hexstring")
455
                {
456
                    string str;
969 runge 457
 
981 runge 458
                    for (int k = 0; k < bits.length(); k += 4)
459
                    {
460
                        str += bin2hex(bits.substr(k, 4));
461
                    }
462
 
463
                    variable.setValue(str);
464
                }
465
 
969 runge 466
                variables[attributes["name"]] = variable;
986 runge 467
            }
969 runge 468
 
986 runge 469
            return variables;
470
        }
471
    }
969 runge 472
 
986 runge 473
    return variables;
474
}
969 runge 475
 
986 runge 476
map<string, CanVariable> CanIdTranslator::translateNMTData(int commandId, string dataHex)
477
{
478
    map<string, CanVariable> variables;
479
    XmlNode commandsNode = xmlNode.findChild("nmt_messages");
480
    vector<XmlNode> commandNodes = commandsNode.getChildren();
969 runge 481
 
986 runge 482
    string dataBin = hex2bin(dataHex);
969 runge 483
 
986 runge 484
    for (int n = 0; n < commandNodes.size(); n++)
485
    {
486
        map<string, string> attributes = commandNodes[n].getAttributes();
969 runge 487
 
986 runge 488
        if (stoi(attributes["id"]) == commandId)
489
        {
490
            XmlNode varablesNode = commandNodes[n].findChild("variables");
969 runge 491
 
986 runge 492
            vector<XmlNode> variableNodes = varablesNode.getChildren();
493
 
494
            for (int c = 0; c < variableNodes.size(); c++)
495
            {
496
                map<string, string> attributes = variableNodes[c].getAttributes();
497
 
498
                int bitStart = stoi(attributes["start_bit"]);
499
                int bitLength = stoi(attributes["bit_length"]);
500
 
501
                string bits = dataBin.substr(bitStart, bitLength);
502
 
503
                CanVariable variable;
504
 
505
                variable.setName(attributes["name"]);
506
                variable.setType(attributes["type"]);
507
                variable.setUnit(attributes["unit"]);
508
                variable.setBitLength(bitLength);
509
 
510
                if (attributes["type"] == "uint")
511
                {
512
                    variable.setValue(itos(bin2uint(bits)));
513
                }
514
                else if (attributes["type"] == "float")
515
                {
516
                    variable.setValue(ftos(bin2float(bits)));
517
                }
518
                else if (attributes["type"] == "ascii")
519
                {
520
                    string str;
521
 
522
                    for (int k = 0; k < bits.length(); k += 8)
523
                    {
524
                        str += (char)bin2uint(bits.substr(k, 8));
525
                    }
526
 
527
                    variable.setValue(str);
528
                }
529
                else if (attributes["type"] == "hexstring")
530
                {
531
                    string str;
532
 
533
                    for (int k = 0; k < bits.length(); k += 4)
534
                    {
535
                        str += bin2hex(bits.substr(k, 4));
536
                    }
537
 
538
                    variable.setValue(str);
539
                }
540
 
541
                variables[attributes["name"]] = variable;
542
            }
543
 
969 runge 544
            return variables;
545
        }
546
    }
547
 
548
    //return dataString + " ]";
549
    return variables;
550
}
551
 
986 runge 552
string CanIdTranslator::translateNMTDataToHex(int commandId, map<string, CanVariable> data)
969 runge 553
{
986 runge 554
    XmlNode commandsNode = xmlNode.findChild("nmt_messages");
555
    vector<XmlNode> commandNodes = commandsNode.getChildren();
969 runge 556
 
986 runge 557
    map<string, CanVariable> sortedData;
969 runge 558
 
986 runge 559
    for (int n = 0; n < commandNodes.size(); n++)
560
    {
561
        map<string, string> attributes = commandNodes[n].getAttributes();
969 runge 562
 
986 runge 563
        if (stoi(attributes["id"]) == commandId)
564
        {
565
            XmlNode varablesNode = commandNodes[n].findChild("variables");
969 runge 566
 
986 runge 567
            vector<XmlNode> variableNodes = varablesNode.getChildren();
969 runge 568
 
986 runge 569
            for (int c = 0; c < variableNodes.size(); c++)
570
            {
571
                map<string, string> attributes = variableNodes[c].getAttributes();
572
 
573
                if (data.find(attributes["name"]) != data.end())
574
                {
575
                    int bitStart = stoi(attributes["start_bit"]);///FIXME: This is not a good way
576
                    int bitLength = stoi(attributes["bit_length"]);
577
 
578
                    sortedData[attributes["name"]].setType(attributes["type"]);
579
                    sortedData[attributes["name"]].setUnit(attributes["unit"]);
580
                    sortedData[attributes["name"]].setBitLength(bitLength);
581
                    sortedData[attributes["name"]].setBitLength(bitLength);
582
                    sortedData[attributes["name"]].setStartBit(bitStart);
583
                    sortedData[attributes["name"]].setName(attributes["name"]);
584
                    sortedData[attributes["name"]].setValue(data[attributes["name"]].getValue());
585
                }
586
            }
587
        }
588
    }
589
 
590
    string bin = "0000000000000000000000000000000000000000000000000000000000000000";
591
    int heighestBit = 0;
592
 
593
    map<string, CanVariable>::iterator iter;
594
 
595
    for (iter = sortedData.begin(); iter != sortedData.end(); iter++)///FIXME: We should check order and length
596
    {
597
        if (iter->second.getType() == "uint")
598
        {
599
            if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
600
                heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
601
 
602
            //cout << iter->first << ":" <<  stoi(iter->second.getValue()) << endl;
603
            unsigned int a = stoi(iter->second.getValue());
604
 
605
            bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), uint2bin(a, iter->second.getBitLength()));
606
        }
607
        else if (iter->second.getType() == "float")
608
        {
609
            if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
610
                heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
611
 
612
            bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), float2bin(stof(iter->second.getValue()), iter->second.getBitLength()));
613
        }
614
        else if (iter->second.getType() == "ascii")
615
        {
616
            //cout << iter->second.getValue() << endl;
617
            for (int n = 0; n < iter->second.getValue().length(); n++)
618
            {
619
                if (iter->second.getStartBit()+n*8 + 8 > heighestBit)
620
                    heighestBit = iter->second.getStartBit()+n*8 + 8;
621
 
622
                //cout << iter->second.getValue()[n] << ":" << (unsigned int)iter->second.getValue()[n] << endl;
623
                bin.replace(iter->second.getStartBit()+n*8, 8, uint2bin((unsigned int)iter->second.getValue()[n], 8));
624
            }
625
        }
626
        else if (iter->second.getType() == "hexstring")
627
        {
628
            for (int n = 0; n < iter->second.getValue().length(); n++)
629
            {
630
                if (iter->second.getStartBit()+n*4 + 4 > heighestBit)
631
                    heighestBit = iter->second.getStartBit()+n*4 + 4;
632
 
633
                string character;
634
                character += iter->second.getValue()[n];
635
 
636
                bin.replace(iter->second.getStartBit()+n*4, 4, hex2bin(character));
637
            }
638
        }
639
    }
640
 
641
    bin = bin.substr(0, heighestBit);
642
 
643
    //cout << bin2hex(bin) << endl;
644
 
645
    return bin2hex(bin);
969 runge 646
}
986 runge 647