Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
1309 runge 1
/*
2
 * CanNet.cpp
3
 *
4
 *  Created on: Apr 27, 2009
5
 *      Author: Mattias Runge
6
 */
7
 
8
#include "CanNet.h"
9
#include <iostream>
10
 
11
using namespace std;
12
 
13
namespace atom {
14
namespace subscribers {
15
 
16
// TODO Fix input on the form of a URL:
17
// ex. udp://192.168.1.250:1100
18
// ex. dev://dev/ttyUSB0:57000
19
CanNet::CanNet(Broker::pointer broker, string address, unsigned int port) : Subscriber(broker, false)
20
{
21
    LOG.setName("CanNetSubscriber");
22
 
23
    this->myUdpServer = UdpServer::getInstance(port);
24
    (*this->myUdpServer).connect(boost::bind(&CanNet::onNewData, this, _1, _2));
25
 
26
    this->myEndpoint = (*this->myUdpServer).getEndpoint(address);
27
 
28
    this->sendPing();
29
 
30
    this->start();
31
}
32
 
33
CanNet::~CanNet()
34
{
35
}
36
 
37
byte_list CanNet::buildPacket(unsigned int id, byte_list data)
38
{
39
    byte_list packet;
40
 
41
    packet.push_back((unsigned char) PACKET_START);
42
 
43
    packet.push_back((unsigned char) (id & 0xFF));
44
    packet.push_back((unsigned char) ((id >> 8) & 0xFF));
45
    packet.push_back((unsigned char) ((id >> 16) & 0xFF));
46
    packet.push_back((unsigned char) ((id >> 24) & 0xFF));
47
 
48
    packet.push_back((unsigned char) 1); // Ext
49
    packet.push_back((char) 0); // Rtr
50
 
51
    packet.push_back((unsigned char) data.size());
52
 
53
    for (unsigned char n = 0; n < 8; n++)
54
    {
55
        if (n < data.size())
56
        {
57
            packet.push_back(data[n]);
58
        }
59
        else
60
        {
61
            packet.push_back(' ');
62
        }
63
    }
64
 
65
    packet.push_back((unsigned char) PACKET_END);
66
 
67
    return packet;
68
}
69
 
70
void CanNet::processBuffer()
71
{
72
    if (this->myBuffer.size() != 15)
73
    {
74
        LOG.warn("Received packet of length " + itos(this->myBuffer.size() + 2) + ", should be 17.");
75
        this->myBuffer.clear();
76
        return;
77
    }
78
 
79
    byte_list data;
80
 
81
    data.push_back(this->myBuffer[0]);
82
    data.push_back(this->myBuffer[1]);
83
    data.push_back(this->myBuffer[2]);
84
    data.push_back(this->myBuffer[3]);
85
 
86
    unsigned char length = this->myBuffer[4];
87
 
88
    for (unsigned char n = 0; n < length; n++)
89
    {
90
        data.push_back(this->myBuffer[5 + n]);
91
    }
92
 
93
 
94
    BitBuffer buffer(data);
95
 
96
    Header header;
97
 
98
    header.readBits(buffer);
99
 
1310 runge 100
    // TODO how do we convert from moduleType and messageId to their string names... where are these ids stored?
1309 runge 101
 
1310 runge 102
    /*string moduleType = header.getVariable("moduleType").getValue().
103
    unsigned int moduleId = header.getVariable("moduleId").getValue().
104
    string messageType = header.getVariable("messageId").getValue().
1309 runge 105
 
1310 runge 106
    Message::pointer message = boost::make_shared<Message>(moduletype, moduleId, messageType);
1309 runge 107
 
1310 runge 108
    message.readBits(buffer);
1309 runge 109
 
1310 runge 110
    this->put(message);*/
1309 runge 111
 
112
    this->myBuffer.clear();
113
}
114
 
115
void CanNet::sendPing()
116
{
117
    byte_list data(1, (unsigned char) PACKET_PING);
118
 
119
    LOG.info("Sending ping packet...");
120
    (*this->myUdpServer).sendTo(this->myEndpoint, data);
121
}
122
 
123
void CanNet::onNewMessage(Message::pointer message)
124
{
125
    LOG.debug("update called");
126
 
127
    BitBuffer buffer;
128
    // TODO Convert message-variables to bitbuffer then to byte_list
129
    byte_list data;
130
 
131
    // TODO Convert message-id to long
132
    unsigned long id;
133
 
134
    (*this->myUdpServer).sendTo(this->myEndpoint, buildPacket(id, data));
135
}
136
 
137
void CanNet::onNewData(const udp::endpoint & sender, const byte_list & bytes)
138
{
139
    //LOG.debug(udp::endpoint(sender).address().to_string() + "==" + this->myEndpoint.address().to_string());
140
    //LOG.debug(itos(udp::endpoint(sender).port()) + "==" + itos(this->myEndpoint.port()));
141
    if (sender.address() == this->myEndpoint.address()) // Port is wrong sometimes, therefor we only compare address
142
    {
143
        LOG.debug("Got data.");
144
 
145
        for (unsigned int n = 0; n < bytes.size(); n++)
146
        {
147
            if (bytes[n] == PACKET_START)
148
            {
149
                this->myBuffer.clear();
150
            }
151
            else if (bytes[n] == PACKET_END)
152
            {
153
                this->processBuffer();
154
            }
155
            else if (bytes[n] == PACKET_PING)
156
            {
157
                LOG.info("Received pong.");
158
            }
159
            else
160
            {
161
                //LOG.info("Received byte. " + itos(bytes[n]));
162
                this->myBuffer.push_back(bytes[n]);
163
            }
164
        }
165
    }
166
    else
167
    {
168
        LOG.debug("This message was not for me.");
169
    }
170
}
171
 
172
}
173
}