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
 *   canmessage.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 <string>
23
#include <iostream>
24
#include "canidtranslator.h"
25
#include "canmessage.h"
26
 
27
void CanMessage::setRaw(string rawHex)
28
{
29
    CanIdTranslator &translator = CanIdTranslator::getInstance();
30
    SyslogStream &slog = SyslogStream::getInstance();
31
 
32
    //PKT 00060102 1 0 00 00 c4
33
 
34
    rawHex = trim(rawHex, '\n');
35
    rawHex = trim(rawHex);
36
 
37
    vector<string> parts = explode(" ", rawHex);
38
 
39
    if (parts.size() < 2 || parts[0].compare("PKT") != 0)
40
    {
41
        slog << "Malformed can message received from canDaemon: \"" << rawHex << "\"\n";
42
        throw new CanMessageException("Malformed can message received from canDaemon");
43
    }
44
 
45
    myRawHeaderBin = hex2bin(parts[1]);
46
 
47
    myIsHeartbeat = (parts[1] == translator.getDefineId("HeartbeatHeader", "None"));
48
 
49
    // This is not a module id header, but heartbeats are sent this way so we want to check it anyway
50
    if (myIsHeartbeat)
51
    {
52
        string rawHexData = "";
53
        for (int n = 4; n < parts.size(); n++)
54
        {
55
            rawHexData += parts[n];
56
        }
57
 
58
        myData = translator.translateHeartbeatData(rawHexData);
59
    }
60
    else
61
    {
62
        myClassName = translator.lookupClassName(bin2uint(myRawHeaderBin.substr(3, 4)));
63
 
64
        if (myClassName == "")
65
        {
66
            myIsUnknown = true;
67
            return;
68
        }
69
 
70
        myDirectionFlag = translator.lookupDirectionFlag(bin2uint(myRawHeaderBin.substr(7, 1)));
71
        myModuleName = translator.lookupModuleName(bin2uint(myRawHeaderBin.substr(8, 8)));
72
 
73
        myModuleId = (unsigned int)bin2uint(myRawHeaderBin.substr(16, 8));
74
 
75
        int commandId = bin2uint(myRawHeaderBin.substr(24, 8));
76
        myCommandName = translator.lookupCommandName(commandId, translator.lookupModuleName(myModuleId));
77
 
78
        string rawHexData = "";
79
        for (int n = 4; n < parts.size(); n++)
80
        {
81
            rawHexData += parts[n];
82
        }
83
 
84
        myData = translator.translateData(commandId, myModuleName, rawHexData);
85
    }
86
}
87
 
88
string CanMessage::getRaw()
89
{
90
    CanIdTranslator &translator = CanIdTranslator::getInstance();
91
 
92
    string rawHex = "PKT ";
93
 
94
    string bin = "000";
95
 
96
    int classId = translator.resolveClassId(myClassName);
97
    if (classId == -1)
98
        bin += "0000";
99
    else
100
        bin += uint2bin(classId, 4);
101
 
102
 
103
    bin += uint2bin(translator.resolveDirectionFlag(myDirectionFlag), 1);
104
 
105
 
106
    int moduleTypeId = translator.resolveModuleId(myModuleName);
107
    if (moduleTypeId == -1)
108
        bin += "00000000";
109
    else
110
        bin += uint2bin(moduleTypeId, 8);
111
 
112
 
113
    int moduleId = myModuleId;
114
    bin += uint2bin(moduleId, 8);
115
 
116
 
117
    int commandNameId = translator.resolveCommandId(myCommandName, myModuleName);
118
    if (commandNameId == -1)
119
        bin += "00000000";
120
    else
121
        bin += uint2bin(commandNameId, 8);
122
 
123
 
124
 
125
    rawHex += bin2hex(bin);
126
 
127
    rawHex += " 1 0";
128
 
129
    string dataHex = translator.translateDataToHex(commandNameId, myModuleName, myData);
130
 
131
    while (dataHex.size() > 0)
132
    {
133
        string hex = dataHex.substr(0, 2);
134
        dataHex.erase(0, 2);
135
        rawHex += " " + hex;
136
    }
137
 
138
    rawHex += "\n";
139
 
140
    return rawHex;
141
}
142
 
143
void CanMessage::setJSON(string json)
144
{
145
    cout << json << "\n";
146
    string data = trim(json, '(');
147
    data = trim(data, ')');
148
    data = trim(data, '{');
149
    data = trim(data, '{');
150
    data = trim(data, ' ');
151
 
152
    vector<string> parts = explode(",", data);
153
 
154
    for (int n = 0; n < parts.size(); n++)
155
    {
156
        string part = trim(parts[n], ' ');
157
        vector<string> innerParts = explode(":", part);
158
 
159
        int c = 0;
160
        if (innerParts[0] == "data")
161
            c++;
162
 
163
        string name = trim(innerParts[c], ' ');
164
        name = trim(name, '{');
165
        name = trim(name, '}');
166
        string value = trim(innerParts[c+1], ' ');
167
        value = trim(value, '{');
168
        value = trim(value, '}');
169
        value = trim(value, '"');
170
 
171
        cout << "\n" << name << "=" << value << "\n";
172
 
173
        if (name == "className")
174
            myClassName = value;
175
        else if (name == "directionFlag")
176
            myDirectionFlag = value;
177
        else if (name == "moduleName")
178
            myModuleName = value;
179
        else if (name == "moduleId")
180
            myModuleId = stoi(value);
181
        else if (name == "commandName")
182
            myCommandName = value;
183
        else
184
        {
185
            CanVariable canVariable(name, value, "", "");
186
            myData[name] = canVariable;
187
        }
188
    }
189
}
190
 
191
string CanMessage::getJSON()
192
{
193
    string json = "{ ";
194
 
195
    json += "className : '" + myClassName + "', ";
196
    json += "directionFlag : '" + myDirectionFlag + "', ";
197
    json += "moduleName : '" + myModuleName + "', ";
198
    json += "moduleId : " + itos(myModuleId) + ", ";
199
    json += "commandName : '" + myCommandName + "', ";
200
 
201
    json += "data : {";
202
 
203
    map<string, CanVariable>::iterator iter;
204
 
205
    for (iter = myData.begin(); iter != myData.end(); iter++)
206
    {
207
        json += " " + iter->first + " : { ";
208
 
209
        json += "unit : '" + iter->second.getUnit() + "', ";
210
        json += "type : '" + iter->second.getType() + "', ";
211
        json += "value : ";
212
 
213
        if (iter->second.getType() == "uint")
214
        {
215
            json += iter->second.getValue();
216
        }
217
        else if (iter->second.getType() == "float")
218
        {
219
            json += iter->second.getValue();
220
        }
221
        else if (iter->second.getType() == "ascii")
222
        {
223
            json += "'" + iter->second.getValue() + "'";
224
        }
225
 
226
        json += " },";
227
    }
228
 
229
    json = trim(json, ',');
230
 
231
    json += " }";
232
 
233
    return json + " }";
234
}
235
 
236
string CanMessage::getJSONData()
237
{
238
    string json = "{";
239
 
240
    map<string, CanVariable>::iterator iter;
241
 
242
    for (iter = myData.begin(); iter != myData.end(); iter++)
243
    {
244
        json += " " + iter->first + " : ";
245
 
246
        if (iter->second.getType() == "uint")
247
        {
248
            json += iter->second.getValue();
249
        }
250
        else if (iter->second.getType() == "float")
251
        {
252
            json += iter->second.getValue();
253
        }
254
        else if (iter->second.getType() == "ascii")
255
        {
256
            json += "'" + escape(iter->second.getValue()) + "'";
257
        }
258
 
259
        json += ",";
260
    }
261
 
262
    json = trim(json, ',');
263
 
264
    return json + " }";
265
}