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
 
151
string CanIdTranslator::getDefineId(string name, string group)
152
{
153
    XmlNode definesNode = xmlNode.findChild("defines");
154
    vector<XmlNode> defineNodes = definesNode.getChildren();
155
 
156
    for (int n = 0; n < defineNodes.size(); n++)
157
    {
158
        map<string, string> attributes = defineNodes[n].getAttributes();
159
 
160
        if (attributes["group"] == group && attributes["name"] == name)
161
        {
162
            return attributes["id"];
163
        }
164
    }
165
 
166
    return "";
167
}
168
 
169
string CanIdTranslator::lookupDirectionFlag(int directionFlag)
170
{
171
    XmlNode definesNode = xmlNode.findChild("defines");
172
    vector<XmlNode> defineNodes = definesNode.getChildren();
173
 
174
    for (int n = 0; n < defineNodes.size(); n++)
175
    {
176
        map<string, string> attributes = defineNodes[n].getAttributes();
177
 
178
        if (attributes["group"].compare("DirectionFlag") == 0 && stoi(attributes["id"]) == directionFlag)
179
        {
180
            return attributes["name"];
181
        }
182
    }
183
 
184
    return "";
185
}
186
 
187
int CanIdTranslator::resolveDirectionFlag(string directionName)
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"].compare("DirectionFlag") == 0 && attributes["name"].compare(directionName) == 0)
197
        {
198
            return stoi(attributes["id"]);
199
        }
200
    }
201
 
202
    return -1;
203
}
204
 
205
string CanIdTranslator::lookupModuleName(int moduleId)
206
{
207
    XmlNode modulesNode = xmlNode.findChild("modules");
208
    vector<XmlNode> moduleNodes = modulesNode.getChildren();
209
 
210
    for (int n = 0; n < moduleNodes.size(); n++)
211
    {
212
        map<string, string> attributes = moduleNodes[n].getAttributes();
213
 
214
        if (stoi(attributes["id"]) == moduleId)
215
        {
216
            return attributes["name"];
217
        }
218
    }
219
 
220
    return "";
221
}
222
 
223
int CanIdTranslator::resolveModuleId(string moduleName)
224
{
225
    XmlNode modulesNode = xmlNode.findChild("modules");
226
    vector<XmlNode> moduleNodes = modulesNode.getChildren();
227
 
228
    for (int n = 0; n < moduleNodes.size(); n++)
229
    {
230
        map<string, string> attributes = moduleNodes[n].getAttributes();
231
 
232
        if (attributes["name"].compare(moduleName) == 0)
233
        {
234
            return stoi(attributes["id"]);
235
        }
236
    }
237
 
238
    return -1;
239
}
240
 
241
string CanIdTranslator::translateDataToHex(int commandId, string moduleName, map<string, CanVariable> data)
242
{
243
    XmlNode commandsNode = xmlNode.findChild("commands");
244
    vector<XmlNode> commandNodes = commandsNode.getChildren();
245
 
246
    map<string, CanVariable> sortedData;
247
 
248
    for (int n = 0; n < commandNodes.size(); n++)
249
    {
250
        map<string, string> attributes = commandNodes[n].getAttributes();
251
 
252
        bool correct = false;
253
 
981 runge 254
        if (commandId >= 128)
969 runge 255
        {
256
            if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
257
            {
258
                correct = true;
259
            }
260
        }
261
        else if (stoi(attributes["id"]) == commandId)
262
        {
263
            correct = true;
264
        }
265
 
266
        if (correct)
267
        {
268
            XmlNode varablesNode = commandNodes[n].findChild("variables");
269
 
270
            vector<XmlNode> variableNodes = varablesNode.getChildren();
271
 
272
            for (int c = 0; c < variableNodes.size(); c++)
273
            {
274
                map<string, string> attributes = variableNodes[c].getAttributes();
275
 
276
                if (data.find(attributes["name"]) != data.end())
277
                {
278
                    int bitStart = stoi(attributes["start_bit"]);///FIXME: This is not a good way
279
                    int bitLength = stoi(attributes["bit_length"]);
280
 
281
                    sortedData[attributes["name"]].setType(attributes["type"]);
282
                    sortedData[attributes["name"]].setUnit(attributes["unit"]);
283
                    sortedData[attributes["name"]].setBitLength(bitLength);
284
                    sortedData[attributes["name"]].setBitLength(bitLength);
285
                    sortedData[attributes["name"]].setStartBit(bitStart);
286
                    sortedData[attributes["name"]].setName(attributes["name"]);
287
                    sortedData[attributes["name"]].setValue(data[attributes["name"]].getValue());
288
                }
289
            }
290
        }
291
    }
292
 
293
    string bin = "0000000000000000000000000000000000000000000000000000000000000000";
294
    int heighestBit = 0;
295
 
296
    map<string, CanVariable>::iterator iter;
297
 
298
    for (iter = sortedData.begin(); iter != sortedData.end(); iter++)///FIXME: We should check order and length
299
    {
300
        if (iter->second.getType() == "uint")
301
        {
302
            if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
303
                heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
304
 
305
            //cout << iter->first << ":" <<  stoi(iter->second.getValue()) << endl;
981 runge 306
            unsigned int a = stoi(iter->second.getValue());
969 runge 307
 
308
            bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), uint2bin(a, iter->second.getBitLength()));
309
        }
310
        else if (iter->second.getType() == "float")
311
        {
312
            if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
313
                heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
314
 
315
            bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), float2bin(stof(iter->second.getValue()), iter->second.getBitLength()));
316
        }
317
        else if (iter->second.getType() == "ascii")
318
        {
319
            //cout << iter->second.getValue() << endl;
320
            for (int n = 0; n < iter->second.getValue().length(); n++)
321
            {
322
                if (iter->second.getStartBit()+n*8 + 8 > heighestBit)
323
                    heighestBit = iter->second.getStartBit()+n*8 + 8;
324
 
325
                //cout << iter->second.getValue()[n] << ":" << (unsigned int)iter->second.getValue()[n] << endl;
326
                bin.replace(iter->second.getStartBit()+n*8, 8, uint2bin((unsigned int)iter->second.getValue()[n], 8));
327
            }
328
        }
981 runge 329
        else if (iter->second.getType() == "hexstring")
330
        {
331
            for (int n = 0; n < iter->second.getValue().length(); n++)
332
            {
333
                if (iter->second.getStartBit()+n*4 + 4 > heighestBit)
334
                    heighestBit = iter->second.getStartBit()+n*4 + 4;
335
 
336
                string character;
337
                character += iter->second.getValue()[n];
338
 
339
                bin.replace(iter->second.getStartBit()+n*4, 4, hex2bin(character));
340
            }
341
        }
969 runge 342
    }
343
 
344
    bin = bin.substr(0, heighestBit);
345
 
346
    //cout << bin2hex(bin) << endl;
347
 
348
    return bin2hex(bin);
349
}
350
 
351
map<string, CanVariable> CanIdTranslator::translateData(int commandId, string moduleName, string dataHex)
352
{
353
    map<string, CanVariable> variables;
354
    XmlNode commandsNode = xmlNode.findChild("commands");
355
    vector<XmlNode> commandNodes = commandsNode.getChildren();
356
 
357
    string dataBin = hex2bin(dataHex);
358
    //string dataString = "{";
359
 
360
    for (int n = 0; n < commandNodes.size(); n++)
361
    {
362
        map<string, string> attributes = commandNodes[n].getAttributes();
363
 
364
        bool correct = false;
365
 
981 runge 366
        if (commandId >= 128)
969 runge 367
        {
368
            if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
369
            {
370
                correct = true;
371
            }
372
        }
373
        else if (stoi(attributes["id"]) == commandId)
374
        {
375
            correct = true;
376
        }
377
 
378
        if (correct)
379
        {
380
            XmlNode varablesNode = commandNodes[n].findChild("variables");
381
 
382
            vector<XmlNode> variableNodes = varablesNode.getChildren();
383
 
384
            for (int c = 0; c < variableNodes.size(); c++)
385
            {
386
                map<string, string> attributes = variableNodes[c].getAttributes();
387
 
388
                int bitStart = stoi(attributes["start_bit"]);
389
                int bitLength = stoi(attributes["bit_length"]);
390
 
391
                string bits = dataBin.substr(bitStart, bitLength);
392
 
393
                CanVariable variable;
394
 
395
                variable.setName(attributes["name"]);
396
                variable.setType(attributes["type"]);
397
                variable.setUnit(attributes["unit"]);
398
                variable.setBitLength(bitLength);
399
 
400
                //dataString += " " + attributes["name"] + " : { value : ";
401
                //dataString += attributes["name"] + "=";
402
                //dataString += attributes["name"] + ":" + attributes["type"] + ":" + attributes["bit_length"] + "=\"";
403
 
404
                if (attributes["type"] == "uint")
405
                {
406
                    variable.setValue(itos(bin2uint(bits)));
407
                    //dataString += itos(bin2uint(bits));
408
                }
409
                else if (attributes["type"] == "float")
410
                {
411
                    variable.setValue(ftos(bin2float(bits)));
412
                    //dataString += ftos(bin2float(bits));
413
                }
414
                else if (attributes["type"] == "ascii")
415
                {
416
                    string str;
417
                    //dataString += "'";
418
 
419
                    for (int k = 0; k < bits.length(); k += 8)
420
                    {
421
                        str += (char)bin2uint(bits.substr(k, 8));
422
                        //dataString += (char)bin2uint(bits.substr(k, 4));
423
                    }
424
 
425
                    variable.setValue(str);
426
                    //cout << "Parsed ascii: " << str << "\n";
427
                    //dataString += "'";
428
                }
981 runge 429
                else if (attributes["type"] == "hexstring")
430
                {
431
                    string str;
969 runge 432
 
981 runge 433
                    for (int k = 0; k < bits.length(); k += 4)
434
                    {
435
                        str += bin2hex(bits.substr(k, 4));
436
                        //dataString += (char)bin2uint(bits.substr(k, 4));
437
                    }
438
 
439
                    variable.setValue(str);
440
                }
441
 
969 runge 442
                variables[attributes["name"]] = variable;
443
 
444
                //dataString += ", type : '" + attributes["type"] + "', bits : " + attributes["bit_length"] + ", unit : '" + attributes["unit"] + "' },";
445
 
446
                //dataString += ",";
447
                //dataString += "\",";
448
            }
449
 
450
            //dataString = trim(dataString, ',');
451
 
452
            //dataString += " }";
453
 
454
            //return dataString;
455
 
456
 
457
            return variables;
458
        }
459
    }
460
 
461
    //return dataString + " ]";
462
    return variables;
463
}
464
 
465
map<string, CanVariable> CanIdTranslator::translateHeartbeatData(string dataHex)
466
{
467
    map<string, CanVariable> variables;
468
 
469
    string dataBin = hex2bin(dataHex);
470
    string bits = dataBin.substr(0, 32);
471
 
472
    CanVariable canVariable("HardwareId", itos(bin2uint(bits)), "uint", "");
473
    canVariable.setBitLength(32);
474
 
475
    variables["HardwareId"] = canVariable;
476
 
477
    return variables;
478
 
479
    //return "{ HardwareId : { value : " + itos(bin2uint(bits)) + ", type : 'uint', bits : 32, unit : '' }";
480
    //return "HardwareId:uint:32=\"" + itos(bin2uint(bits)) + "\"";
481
}