Subversion Repositories HomeAutomation

Rev

Rev 1646 | Rev 1766 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
1596 runge 1
/*
2
 *
3
 *  Copyright (C) 2010  Mattias Runge
4
 *
5
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License along
16
 *  with this program; if not, write to the Free Software Foundation, Inc.,
17
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
 *
19
 */
20
 
21
#include "Protocol.h"
22
 
23
#include <stdexcept>
1598 runge 24
#include <string.h>
1596 runge 25
 
26
#include <boost/lexical_cast.hpp>
27
 
28
namespace atom {
29
namespace can {
30
 
1599 runge 31
Protocol::Pointer Protocol::instance_;
1596 runge 32
 
33
Protocol::Protocol() : LOG("can::Protocol")
34
{
35
}
36
 
37
Protocol::~Protocol()
38
{
39
}
40
 
1599 runge 41
void Protocol::Create()
42
{
43
    Protocol::instance_ = Protocol::Pointer(new Protocol());
44
}
45
 
1596 runge 46
Protocol::Pointer Protocol::Instance()
47
{
48
    return Protocol::instance_;
49
}
50
 
51
void Protocol::Delete()
52
{
53
    Protocol::instance_.reset();
54
}
55
 
56
bool Protocol::Load(std::string filename)
57
{
58
    try
59
    {
60
        this->root_node_.LoadFile(filename);
61
    }
62
    catch (std::runtime_error& e)
63
    {
64
        LOG.Error(e.what());
65
        return false;
66
    }
67
 
1598 runge 68
    LOG.Info("Protocol loaded successfully.");
1596 runge 69
    return true;
70
}
71
 
72
std::string Protocol::LookupClassName(unsigned int class_id)
73
{
74
    try
75
    {
76
        return this->root_node_.FindChild("classes").SelectChild("id", boost::lexical_cast<std::string>(class_id)).GetAttributeValue("name");
77
    }
78
    catch (std::runtime_error& e)
79
    {
80
        LOG.Error(e.what());
81
        throw std::runtime_error("No such class_id found, " + boost::lexical_cast<std::string>(class_id));
82
    }
83
}
84
 
85
unsigned int Protocol::ResolveClassId(std::string class_name)
86
{
87
    try
88
    {
89
        return boost::lexical_cast<unsigned int>(this->root_node_.FindChild("classes").SelectChild("name", class_name).GetAttributeValue("id"));
90
    }
91
    catch (std::runtime_error& e)
92
    {
93
        LOG.Error(e.what());
94
        throw std::runtime_error("No such class_name found, " + class_name);
95
    }
96
}
97
 
98
std::string Protocol::LookupCommandName(unsigned int command_id, std::string module_name)
99
{
100
    try
101
    {
102
        if (command_id >= 128)
103
        {
104
            return this->root_node_.FindChild("commands").SelectChild("id", boost::lexical_cast<std::string>(command_id), "module", module_name).GetAttributeValue("name");
105
        }
106
 
107
        return this->root_node_.FindChild("commands").SelectChild("id", boost::lexical_cast<std::string>(command_id)).GetAttributeValue("name");
108
    }
109
    catch (std::runtime_error& e)
110
    {
111
        LOG.Error(e.what());
112
        throw std::runtime_error("No such command found, id = " + boost::lexical_cast<std::string>(command_id) + ", module = " + module_name);
113
    }
114
}
115
 
116
unsigned int Protocol::ResolveCommandId(std::string command_name, std::string module_name)
117
{
118
    try
119
    {
120
        return boost::lexical_cast<unsigned int >(this->root_node_.FindChild("commands").SelectChild("name", command_name, "module", module_name).GetAttributeValue("id"));
121
    }
122
    catch (std::runtime_error& e)
123
    {
124
    }
125
 
126
    try
127
    {
128
        return boost::lexical_cast<unsigned int >(this->root_node_.FindChild("commands").SelectChild("name", command_name).GetAttributeValue("id"));
129
    }
130
    catch (std::runtime_error& e)
131
    {
132
        LOG.Error(e.what());
133
        throw std::runtime_error("No such command found, name = " + command_name + ", module = " + module_name);
134
    }
135
}
136
 
137
std::string Protocol::LookupNMTCommandName(unsigned int command_id)
138
{
139
    try
140
    {
141
        return this->root_node_.FindChild("nmt_messages").SelectChild("id", boost::lexical_cast<std::string>(command_id)).GetAttributeValue("name");
142
    }
143
    catch (std::runtime_error& e)
144
    {
145
        LOG.Error(e.what());
146
        throw std::runtime_error("No such nmt command found, id = " + boost::lexical_cast<std::string>(command_id));
147
    }
148
}
149
 
150
unsigned int Protocol::ResolveNMTCommandId(std::string command_name)
151
{
152
    try
153
    {
154
        return boost::lexical_cast<unsigned int >(this->root_node_.FindChild("nmt_messages").SelectChild("name", command_name).GetAttributeValue("id"));
155
    }
156
    catch (std::runtime_error& e)
157
    {
158
        LOG.Error(e.what());
159
        throw std::runtime_error("No such nmt command found, name = " + command_name);
160
    }
161
}
162
 
163
std::string Protocol::GetDefineId(std::string name, std::string group)
164
{
165
    try
166
    {
167
        return this->root_node_.FindChild("defines").SelectChild("name", name, "group", group).GetAttributeValue("id");
168
    }
169
    catch (std::runtime_error& e)
170
    {
171
        LOG.Error(e.what());
172
        throw std::runtime_error("No such define found, name = " + name + ", group = " + group);
173
    }
174
}
175
 
176
std::string Protocol::LookupDirectionFlag(unsigned int direction_flag)
177
{
178
    try
179
    {
180
        return this->root_node_.FindChild("defines").SelectChild("id", boost::lexical_cast<std::string>(direction_flag), "group", "DirectionFlag").GetAttributeValue("name");
181
    }
182
    catch (std::runtime_error& e)
183
    {
184
        LOG.Error(e.what());
185
        throw std::runtime_error("No such direction flag found, direction_flag = " + boost::lexical_cast<std::string>(direction_flag));
186
    }
187
}
188
 
189
unsigned int Protocol::ResolveDirectionFlag(std::string direction_name)
190
{
191
    try
192
    {
193
        return boost::lexical_cast<unsigned int>(this->root_node_.FindChild("defines").SelectChild("name", direction_name, "group", "DirectionFlag").GetAttributeValue("id"));
194
    }
195
    catch (std::runtime_error& e)
196
    {
197
        LOG.Error(e.what());
198
        throw std::runtime_error("No such direction flag found, direction_name = " + direction_name);
199
    }
200
}
201
 
202
std::string Protocol::LookupModuleName(unsigned int module_id)
203
{
204
    try
205
    {
206
        return this->root_node_.FindChild("modules").SelectChild("id", boost::lexical_cast<std::string>(module_id)).GetAttributeValue("name");
207
    }
208
    catch (std::runtime_error& e)
209
    {
210
        LOG.Error(e.what());
211
        throw std::runtime_error("No such module id found, " + boost::lexical_cast<std::string>(module_id));
212
    }
213
}
214
 
215
unsigned int Protocol::ResolveModuleId(std::string module_name)
216
{
1598 runge 217
    if (module_name == "")
218
    {
219
        return 0;
220
    }
221
 
1596 runge 222
    try
223
    {
224
        return boost::lexical_cast<unsigned int>(this->root_node_.FindChild("modules").SelectChild("name", module_name).GetAttributeValue("id"));
225
    }
226
    catch (std::runtime_error& e)
227
    {
228
        LOG.Error(e.what());
229
        throw std::runtime_error("No such module name found, " + module_name);
230
    }
231
}
232
 
233
xml::Node::NodeList Protocol::GetCommandVariables(std::string command_name, std::string module_name)
234
{
1605 runge 235
    xml::Node node;
236
 
1596 runge 237
    try
238
    {
1605 runge 239
        node = this->root_node_.FindChild("commands").SelectChild("name", command_name, "module", module_name);
240
 
241
        try
242
        {
243
            return node.FindChild("variables").GetChildren();
244
        }
245
        catch (std::runtime_error& e)
246
        {
247
            return xml::Node::NodeList();
248
        }
1596 runge 249
    }
250
    catch (std::runtime_error& e)
251
    {
252
    }
1605 runge 253
 
1596 runge 254
 
255
    try
256
    {
1605 runge 257
        node = this->root_node_.FindChild("commands").SelectChild("name", command_name);
258
 
259
        try
260
        {
261
            return node.FindChild("variables").GetChildren();
262
        }
263
        catch (std::runtime_error& e)
264
        {
265
            return xml::Node::NodeList();
266
        }
1596 runge 267
    }
268
    catch (std::runtime_error& e)
269
    {
270
        LOG.Error(e.what());
1605 runge 271
        throw std::runtime_error("Could not find variables for command, name = " + command_name + ", module = " + module_name);
1596 runge 272
    }
1605 runge 273
 
274
    return xml::Node::NodeList();
1596 runge 275
}
276
 
277
xml::Node::NodeList Protocol::GetNMTCommandVariables(std::string command_name)
278
{
1605 runge 279
    xml::Node node;
280
 
1596 runge 281
    try
282
    {
1605 runge 283
        node = this->root_node_.FindChild("nmt_messages").SelectChild("name", command_name);
284
 
285
        try
286
        {
287
            return node.FindChild("variables").GetChildren();
288
        }
289
        catch (std::runtime_error& e)
290
        {
291
            return xml::Node::NodeList();
292
        }
1596 runge 293
    }
294
    catch (std::runtime_error& e)
295
    {
296
        LOG.Error(e.what());
1605 runge 297
        throw std::runtime_error("Could not find variables for nmt command, name = " + command_name);
1596 runge 298
    }
1605 runge 299
 
300
    return xml::Node::NodeList();
1596 runge 301
}
302
 
1642 runge 303
std::string Protocol::DecodeInt(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length)
1596 runge 304
{
1689 runge 305
    bool sign = bitset.Get(start_bit) == 1;
306
 
1598 runge 307
    unsigned long raw_bit_value = bitset.Read(start_bit, bit_length);
1689 runge 308
 
309
    int raw_value = raw_bit_value;
1596 runge 310
 
1689 runge 311
    if (sign)
312
    {
313
        long mask = 0;
314
 
315
        for (unsigned int n = 0; n < bit_length; n++)
316
        {
317
            mask += (1 << n);
318
        }
319
 
320
        raw_value = -((~raw_bit_value) & mask);
321
    }
322
 
1598 runge 323
    return boost::lexical_cast<std::string>(raw_value);
1596 runge 324
}
325
 
1642 runge 326
void Protocol::EncodeInt(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length, std::string value)
1596 runge 327
{
1598 runge 328
    unsigned long raw_bit_value = 0;
329
    int raw_value = boost::lexical_cast<int>(value);
1596 runge 330
 
1689 runge 331
    raw_bit_value = raw_bit_value;
1598 runge 332
 
1689 runge 333
    if (raw_value < 0)
334
    {
335
        long mask = 0;
336
 
337
        for (unsigned int n = 0; n < bit_length; n++)
338
        {
339
            mask += (1 << n);
340
        }
341
 
342
        raw_bit_value = (~(-raw_value)) & mask;
343
    }
344
 
1598 runge 345
    bitset.Write(start_bit, bit_length, raw_bit_value);
1596 runge 346
}
347
 
1642 runge 348
std::string Protocol::DecodeUint(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length)
1596 runge 349
{
1598 runge 350
    unsigned long raw_bit_value = bitset.Read(start_bit, bit_length);
351
 
1607 runge 352
    //LOG.Debug("DecodeUint: raw_bit_value=" + boost::lexical_cast<std::string>(raw_bit_value));
353
 
1598 runge 354
    return boost::lexical_cast<std::string>((unsigned int)raw_bit_value);
1596 runge 355
}
356
 
1642 runge 357
void Protocol::EncodeUint(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length, std::string value)
1596 runge 358
{
1598 runge 359
    unsigned long raw_bit_value = boost::lexical_cast<unsigned int>(value);
1596 runge 360
 
1598 runge 361
    bitset.Write(start_bit, bit_length, raw_bit_value);
1596 runge 362
}
363
 
1642 runge 364
std::string Protocol::DecodeFloat(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length)
1596 runge 365
{
1689 runge 366
    float float_value = boost::lexical_cast<float>(this->DecodeInt(bitset, start_bit, bit_length));
367
    LOG.Debug("DecodeFloat::float_value1=" + boost::lexical_cast<std::string>(float_value));
1596 runge 368
 
1689 runge 369
 
370
    float_value = float_value / 64.0f;
371
 
372
    LOG.Debug("DecodeFloat::float_value2=" + boost::lexical_cast<std::string>(float_value));
373
 
1600 runge 374
    return boost::lexical_cast<std::string>(float_value);
1596 runge 375
}
376
 
1642 runge 377
void Protocol::EncodeFloat(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length, std::string value)
1596 runge 378
{
1600 runge 379
    int int_value = boost::lexical_cast<float>(value) * 64.0f;
380
 
381
    this->EncodeInt(bitset, start_bit, bit_length, boost::lexical_cast<std::string>(int_value));
1596 runge 382
}
383
 
1642 runge 384
std::string Protocol::DecodeAscii(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length)
1596 runge 385
{
1598 runge 386
    std::string value;
1596 runge 387
 
1600 runge 388
    for (unsigned int n = 0; n < bit_length; n += 8)
1596 runge 389
    {
1600 runge 390
        unsigned long raw_value = bitset.Read(start_bit + n, 8);
391
        value += (char)raw_value;
1596 runge 392
    }
393
 
1598 runge 394
    return value;
1596 runge 395
}
396
 
1642 runge 397
void Protocol::EncodeAscii(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length, std::string value)
1596 runge 398
{
1610 runge 399
    //LOG.Debug("EncodeAscii: " + value + ", length=" + boost::lexical_cast<std::string>(value.length()) + ", bit_length=" + boost::lexical_cast<std::string>(bit_length));
1607 runge 400
 
1600 runge 401
    for (unsigned int n = 0; n < bit_length; n += 8)
402
    {
1610 runge 403
        if (n / 8 >= value.length())
1607 runge 404
        {
405
            break;
406
        }
407
 
1610 runge 408
        //LOG.Debug(boost::lexical_cast<std::string>((unsigned int)value[n / 8]));
409
 
1600 runge 410
        bitset.Write(start_bit + n, 8, value[n / 8]);
411
    }
1598 runge 412
}
413
 
1642 runge 414
std::string Protocol::DecodeHexstring(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length)
1598 runge 415
{
416
    std::string value;
417
    char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1596 runge 418
 
1600 runge 419
    for (unsigned int n = 0; n < bit_length; n += 4)
1596 runge 420
    {
1600 runge 421
        unsigned long raw_bit_value = bitset.Read(start_bit + n, 4);
1596 runge 422
 
1598 runge 423
        if (raw_bit_value >= sizeof(hex))
1596 runge 424
        {
1598 runge 425
            value += '-';
1596 runge 426
        }
1598 runge 427
        else
1596 runge 428
        {
1598 runge 429
            value += hex[raw_bit_value];
1596 runge 430
        }
431
    }
432
 
1598 runge 433
    return value;
1596 runge 434
}
1598 runge 435
 
1642 runge 436
void Protocol::EncodeHexstring(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length, std::string value)
1598 runge 437
{
1600 runge 438
    int ascii_value;
439
 
440
    for (unsigned int n = 0; n < bit_length; n += 4)
441
    {
442
        ascii_value = boost::lexical_cast<int>((int)std::toupper(value[n / 4]));
443
 
444
        if (48 <= ascii_value && ascii_value <= 57)
445
        {
446
            bitset.Write(start_bit + n, 4, ascii_value - 48);
447
        }
448
        else if (65 <= ascii_value && ascii_value <= 70)
449
        {
450
            bitset.Write(start_bit + n, 4, ascii_value - 65);
451
        }
452
        else
453
        {
454
            throw std::runtime_error("This is not an hex string, " + value);
455
        }
456
    }
1598 runge 457
}
458
 
1596 runge 459
}; // namespace can
460
}; // namespace atom