Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
969 runge 1
/***************************************************************************
2
 *   Copyright (C) November 29, 2008 by Mattias Runge                             *
3
 *   mattias@runge.se                                                      *
4
 *   cannetmanager.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 "canmessage.h"
23
#include "cannetmanager.h"
24
 
25
CanNetManager* CanNetManager::myInstance = NULL;
26
 
27
CanNetManager& CanNetManager::getInstance()
28
{
29
    if (myInstance == NULL)
30
    {
31
        myInstance = new CanNetManager();
32
    }
33
 
34
    return *myInstance;
35
}
36
 
37
void CanNetManager::deleteInstance()
38
{
39
    if (myInstance != NULL)
40
    {
41
        delete myInstance;
42
        myInstance = NULL;
43
    }
44
}
45
 
46
CanNetManager::CanNetManager()
47
{
48
    CanIdTranslator &translator = CanIdTranslator::getInstance();
49
    myChannel = new AsyncSocket();
50
}
51
 
52
CanNetManager::~CanNetManager()
53
{
54
    CanIdTranslator::deleteInstance();
983 runge 55
    myChannel->stop();
969 runge 56
    delete myChannel;
57
}
58
 
59
void CanNetManager::openChannel()
60
{
61
    SyslogStream &slog = SyslogStream::getInstance();
62
    VirtualMachine &vm = VirtualMachine::getInstance();
981 runge 63
    CanDebug &canDebug = CanDebug::getInstance();
969 runge 64
 
65
    string address = Settings::get("CanNetAddress");
66
    string port = Settings::get("CanNetPort");
67
 
68
    myChannel->setAddress(address, stoi(port));
69
 
976 runge 70
    myChannel->setReconnectTimeout(10);
71
 
969 runge 72
    myChannel->start();
73
 
74
    myChannel->startEvent();
75
 
974 runge 76
    bool waitingForPong = false;
77
 
969 runge 78
    while (1)
79
    {
80
        myChannel->waitForEvent();
81
 
983 runge 82
        while (myChannel->availableEvent())
83
        {
84
            int event = myChannel->getEvent();
969 runge 85
 
983 runge 86
            if (event == ASYNCSOCKET_EVENT_DATA)
969 runge 87
            {
983 runge 88
                while (myChannel->availableData())
89
                {
90
                    waitingForPong = false;
974 runge 91
 
983 runge 92
                    string data = myChannel->getData();
969 runge 93
 
983 runge 94
                    try
969 runge 95
                    {
983 runge 96
                        ///FIXME: Verify that \n is right here, have seen that it does not always work
97
                        vector<string> dataLines = explode("\n", data);
974 runge 98
 
983 runge 99
                        for (int n = 0; n < dataLines.size(); n++)
974 runge 100
                        {
983 runge 101
                            data = trim(dataLines[n], '\n');
974 runge 102
 
983 runge 103
                            if (data == "PONG")
104
                            {
105
                                slog << "Received pong.\n";
106
                                continue;
107
                            }
969 runge 108
 
983 runge 109
                            CanMessage canMessage;
110
                            canMessage.setRaw(data);
969 runge 111
 
983 runge 112
                            //slog << "Received: " << data;
113
 
114
                            if (!canMessage.isUnknown())
115
                            {
116
                                vm.queueCanMessage(canMessage);
117
                                canDebug.sendCanMessage(canMessage);
118
                            }
119
                            else
120
                            {
121
                                canDebug.sendData(data + "\n");
122
                            }
123
                            /*else
124
                            {
125
                                slog << "Received unknown message. Skipping...\n";
126
                            }*/
969 runge 127
                        }
128
                    }
983 runge 129
                    catch (CanMessageException* e)
130
                    {
131
                        slog << "CanMessageException was caught:\n";
132
                        slog << e->getDescription() + "\n";
133
                    }
969 runge 134
                }
135
            }
983 runge 136
            else if (event == ASYNCSOCKET_EVENT_CONNECTED)
974 runge 137
            {
983 runge 138
                slog << "Connected to " + address + ":" + port + "\n";
139
            }
140
            else if (event == ASYNCSOCKET_EVENT_CLOSED)
141
            {
974 runge 142
                vm.queueExpression("setAllOffline();");
143
            }
983 runge 144
            else if (event == ASYNCSOCKET_EVENT_DIED)
974 runge 145
            {
983 runge 146
                vm.queueExpression("setAllOffline();");
147
                break;
974 runge 148
            }
983 runge 149
            else if (event == ASYNCSOCKET_EVENT_INACTIVITY)
150
            {
151
                if (waitingForPong)
152
                {
153
                    slog << "We have not received a pong for our ping.\n";
154
                    waitingForPong = false;
155
                    vm.queueExpression("setAllOffline();");
156
                    myChannel->forceReconnect();
157
                }
158
                else
159
                {
160
                    //slog << "We have not received anything from the canDaemon in some time.\n";
161
                    waitingForPong = true;
162
                    slog << "Sending ping.\n";
163
                    myChannel->sendData("PING");
164
                }
974 runge 165
 
983 runge 166
            }
974 runge 167
        }
969 runge 168
    }
169
 
170
    myChannel->stopEvent();
171
}
172
 
173
void CanNetManager::sendMessage(CanMessage canMessage)
174
{
981 runge 175
    CanDebug &canDebug = CanDebug::getInstance();
176
    canDebug.sendCanMessage(canMessage);
969 runge 177
    myChannel->sendData(canMessage.getRaw());
178
}
179