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();
976 runge 30
	//SyslogStream &slog = SyslogStream::getInstance();
969 runge 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
	{
976 runge 41
		//slog << "Malformed can message received from canDaemon: \"" << rawHex << "\"\n";
969 runge 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
}