Subversion Repositories HomeAutomation

Rev

Rev 1898 | Rev 1959 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 1898 Rev 1939
1
/*
1
/*
2
 *
2
 *
3
 *  Copyright (C) 2010  Mattias Runge
3
 *  Copyright (C) 2010  Mattias Runge
4
 *
4
 *
5
 *  This program is free software; you can redistribute it and/or modify
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
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
7
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
8
 *  (at your option) any later version.
9
 *
9
 *
10
 *  This program is distributed in the hope that it will be useful,
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
13
 *  GNU General Public License for more details.
14
 *
14
 *
15
 *  You should have received a copy of the GNU General Public License along
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.,
16
 *  with this program; if not, write to the Free Software Foundation, Inc.,
17
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
 *
18
 *
19
 */
19
 */
20
 
20
 
21
#include "Manager.h"
21
#include "Manager.h"
22
 
22
 
23
#include <iostream>
23
#include <iostream>
24
 
24
 
25
#include <boost/lexical_cast.hpp>
25
#include <boost/lexical_cast.hpp>
26
#include <boost/bind.hpp>
26
#include <boost/bind.hpp>
27
#include <boost/cast.hpp>
27
#include <boost/cast.hpp>
28
 
28
 
29
namespace atom {
29
namespace atom {
30
namespace net {
30
namespace net {
31
 
31
 
32
Manager::Pointer Manager::instance_;
32
Manager::Pointer Manager::instance_;
33
   
33
   
34
logging::Logger Manager::LOG("net::Manager");
34
logging::Logger Manager::LOG("net::Manager");
35
 
35
 
36
Manager::Manager()
36
Manager::Manager()
37
{
37
{
38
 
38
 
39
}
39
}
40
 
40
 
41
Manager::~Manager()
41
Manager::~Manager()
42
{
42
{
-
 
43
    this->Stop();
-
 
44
 
43
    this->clients_.clear();
45
    this->clients_.clear();
44
}
46
}
45
 
47
 
46
Manager::Pointer Manager::Instance()
48
Manager::Pointer Manager::Instance()
47
{
49
{
48
    return Manager::instance_;
50
    return Manager::instance_;
49
}
51
}
50
 
52
 
51
void Manager::Create()
53
void Manager::Create()
52
{
54
{
53
    Manager::instance_ = Manager::Pointer(new Manager());
55
    Manager::instance_ = Manager::Pointer(new Manager());
54
}
56
}
55
 
57
 
56
void Manager::Delete()
58
void Manager::Delete()
57
{
59
{
58
    Manager::instance_.reset();
60
    Manager::instance_.reset();
59
}
61
}
60
 
62
 
61
void Manager::ConnectSlots(const SignalOnNewState::slot_type& slot_on_new_state, const SignalOnNewData::slot_type& slot_on_new_data)
63
void Manager::ConnectSlots(const SignalOnNewState::slot_type& slot_on_new_state, const SignalOnNewData::slot_type& slot_on_new_data)
62
{
64
{
63
    this->signal_on_new_state_.connect(slot_on_new_state);
65
    this->signal_on_new_state_.connect(slot_on_new_state);
64
    this->signal_on_new_data_.connect(slot_on_new_data);
66
    this->signal_on_new_data_.connect(slot_on_new_data);
65
}
67
}
66
 
68
 
67
void Manager::SlotOnNewState(ClientId client_id, ServerId server_id, ClientState client_state)
69
void Manager::SlotOnNewState(ClientId client_id, ServerId server_id, ClientState client_state)
68
{
70
{
69
    if (client_state == CLIENT_STATE_DISCONNECTED)
71
    if (client_state == CLIENT_STATE_DISCONNECTED)
70
    {
72
    {
71
        this->clients_.erase(client_id);
73
        this->clients_.erase(client_id);
72
    }
74
    }
73
    else if (client_state == CLIENT_STATE_ACCEPTED)
75
    else if (client_state == CLIENT_STATE_ACCEPTED)
74
    {
76
    {
75
        ClientList::iterator it = this->clients_.find(client_id);
77
        ClientList::iterator it = this->clients_.find(client_id);
76
       
78
       
77
        if (it != this->clients_.end())
79
        if (it != this->clients_.end())
78
        {
80
        {
79
            TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), it->second->GetServerId()));
81
            TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), it->second->GetServerId()));
80
           
82
           
81
            client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
83
            client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
82
                                 Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
84
                                 Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
83
           
85
           
84
            client->Accept(boost::polymorphic_downcast<TcpClient*>(it->second.get())->ReleaseAcceptor());
86
            client->Accept(boost::polymorphic_downcast<TcpClient*>(it->second.get())->ReleaseAcceptor());
85
           
87
           
86
            this->clients_[client->GetId()] = client;
88
            this->clients_[client->GetId()] = client;
87
           
89
           
88
            this->signal_on_new_state_(client_id, server_id, CLIENT_STATE_CONNECTED);
90
            this->signal_on_new_state_(client_id, server_id, CLIENT_STATE_CONNECTED);
89
            return;
91
            return;
90
        }
92
        }
91
        else
93
        else
92
        {
94
        {
93
            throw std::runtime_error("Accepted unknown client!");
95
            throw std::runtime_error("Accepted unknown client!");
94
        }
96
        }
95
    }
97
    }
96
   
98
   
97
    this->signal_on_new_state_(client_id, server_id, client_state);
99
    this->signal_on_new_state_(client_id, server_id, client_state);
98
}
100
}
99
 
101
 
100
void Manager::SlotOnNewData(ClientId client_id, ServerId server_id, common::Byteset data)
102
void Manager::SlotOnNewData(ClientId client_id, ServerId server_id, common::Byteset data)
101
{
103
{
102
    this->signal_on_new_data_(client_id, server_id, data);
104
    this->signal_on_new_data_(client_id, server_id, data);
103
}
105
}
104
 
106
 
105
ServerId Manager::GetFreeServerId()
107
ServerId Manager::GetFreeServerId()
106
{
108
{
107
    ServerId server_id = 1;
109
    ServerId server_id = 1;
108
   
110
   
109
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
111
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
110
    {
112
    {
111
        if (it->second->GetServerId() != server_id)
113
        if (it->second->GetServerId() != server_id)
112
        {
114
        {
113
            return server_id;
115
            return server_id;
114
        }
116
        }
115
       
117
       
116
        server_id++;
118
        server_id++;
117
    }
119
    }
118
   
120
   
119
    return server_id;
121
    return server_id;
120
}
122
}
121
 
123
 
122
ClientId Manager::GetFreeClientId()
124
ClientId Manager::GetFreeClientId()
123
{
125
{
124
    ClientId client_id = 1;
126
    ClientId client_id = 1;
125
   
127
   
126
    while (this->clients_.find(client_id) != this->clients_.end())
128
    while (this->clients_.find(client_id) != this->clients_.end())
127
    {
129
    {
128
        client_id++;
130
        client_id++;
129
    }
131
    }
130
   
132
   
131
    return client_id;
133
    return client_id;
132
}
134
}
133
 
135
 
134
ServerId Manager::StartServer(Protocol protocol, unsigned int port)
136
ServerId Manager::StartServer(Protocol protocol, unsigned int port)
135
{
137
{
136
    if (protocol != PROTOCOL_TCP)
138
    if (protocol != PROTOCOL_TCP)
137
    {
139
    {
138
        throw std::runtime_error("Can not start server for the Serial or UDP protocol!");
140
        throw std::runtime_error("Can not start server for the Serial or UDP protocol!");
139
        return 0;
141
        return 0;
140
    }
142
    }
141
   
143
   
142
    TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), this->GetFreeServerId()));
144
    TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), this->GetFreeServerId()));
143
   
145
   
144
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
146
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
145
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
147
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
146
   
148
   
147
    TcpClient::AcceptorPointer acceptor = TcpClient::AcceptorPointer(new boost::asio::ip::tcp::acceptor(this->io_service_, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)));    
149
    TcpClient::AcceptorPointer acceptor = TcpClient::AcceptorPointer(new boost::asio::ip::tcp::acceptor(this->io_service_, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)));    
148
 
150
 
149
    client->Accept(acceptor);
151
    client->Accept(acceptor);
150
   
152
   
151
    this->clients_[client->GetId()] = client;
153
    this->clients_[client->GetId()] = client;
152
   
154
   
153
    return client->GetServerId();
155
    return client->GetServerId();
154
}
156
}
155
 
157
 
156
ClientId Manager::Connect(Protocol protocol, std::string address, unsigned int port_or_baud)
158
ClientId Manager::Connect(Protocol protocol, std::string address, unsigned int port_or_baud)
157
{
159
{
158
    Client::Pointer client;
160
    Client::Pointer client;
159
   
161
   
160
    switch (protocol)
162
    switch (protocol)
161
    {
163
    {
162
        case PROTOCOL_TCP:
164
        case PROTOCOL_TCP:
163
        {
165
        {
164
            client = Client::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), 0));
166
            client = Client::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), 0));
165
            break;
167
            break;
166
        }
168
        }
167
        case PROTOCOL_UDP:
169
        case PROTOCOL_UDP:
168
        {
170
        {
169
            client = Client::Pointer(new UdpClient(this->io_service_, this->GetFreeClientId(), 0));
171
            client = Client::Pointer(new UdpClient(this->io_service_, this->GetFreeClientId(), 0));
170
            break;
172
            break;
171
        }
173
        }
172
        case PROTOCOL_SERIAL:
174
        case PROTOCOL_SERIAL:
173
        {
175
        {
174
            client = Client::Pointer(new SerialClient(this->io_service_, this->GetFreeClientId(), 0));
176
            client = Client::Pointer(new SerialClient(this->io_service_, this->GetFreeClientId(), 0));
175
            break;
177
            break;
176
        }
178
        }
177
        default:
179
        default:
178
        {
180
        {
179
            throw std::runtime_error("Invalid protocol specified!");
181
            throw std::runtime_error("Invalid protocol specified!");
180
            return 0;
182
            return 0;
181
        }
183
        }
182
    }
184
    }
183
   
185
   
184
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
186
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
185
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
187
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
186
   
188
   
187
    client->Connect(address, port_or_baud);
189
    client->Connect(address, port_or_baud);
188
   
190
   
189
    this->clients_[client->GetId()] = client;
191
    this->clients_[client->GetId()] = client;
190
   
192
   
191
    return client->GetId();
193
    return client->GetId();
192
}
194
}
193
 
195
 
194
void Manager::SendToAll(ServerId server_id, common::Byteset data)
196
void Manager::SendToAll(ServerId server_id, common::Byteset data)
195
{
197
{
196
    this->io_service_.post(boost::bind(&Manager::SendToAllHandler, this, server_id, data));
198
    this->io_service_.post(boost::bind(&Manager::SendToAllHandler, this, server_id, data));
197
}
199
}
198
 
200
 
199
void Manager::SendTo(ClientId client_id, common::Byteset data)
201
void Manager::SendTo(ClientId client_id, common::Byteset data)
200
{
202
{
201
    this->io_service_.post(boost::bind(&Manager::SendToHandler, this, client_id, data));
203
    this->io_service_.post(boost::bind(&Manager::SendToHandler, this, client_id, data));
202
}
204
}
203
 
205
 
204
void Manager::StopServer(ServerId server_id)
206
void Manager::StopServer(ServerId server_id)
205
{
207
{
206
    this->io_service_.post(boost::bind(&Manager::StopServerHandler, this, server_id));
208
    this->io_service_.post(boost::bind(&Manager::StopServerHandler, this, server_id));
207
}
209
}
208
 
210
 
209
void Manager::Disconnect(ClientId client_id)
211
void Manager::Disconnect(ClientId client_id)
210
{
212
{
211
    this->io_service_.post(boost::bind(&Manager::DisconnectHandler, this, client_id));
213
    this->io_service_.post(boost::bind(&Manager::DisconnectHandler, this, client_id));
212
}
214
}
213
 
215
 
214
void Manager::SendToAllHandler(ServerId server_id, common::Byteset data)
216
void Manager::SendToAllHandler(ServerId server_id, common::Byteset data)
215
{
217
{
216
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
218
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
217
    {
219
    {
218
        if (it->second->GetServerId() == server_id)
220
        if (it->second->GetServerId() == server_id)
219
        {
221
        {
220
            it->second->Send(data);
222
            it->second->Send(data);
221
        }
223
        }
222
    }
224
    }
223
}
225
}
224
 
226
 
225
void Manager::SendToHandler(ClientId client_id, common::Byteset data)
227
void Manager::SendToHandler(ClientId client_id, common::Byteset data)
226
{
228
{
227
    ClientList::iterator it = this->clients_.find(client_id);
229
    ClientList::iterator it = this->clients_.find(client_id);
228
 
230
 
229
    if (it != this->clients_.end())
231
    if (it != this->clients_.end())
230
    {
232
    {
231
        it->second->Send(data);
233
        it->second->Send(data);
232
    }
234
    }
233
}
235
}
234
 
236
 
235
void Manager::StopServerHandler(ServerId server_id)
237
void Manager::StopServerHandler(ServerId server_id)
236
{
238
{
237
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
239
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
238
    {
240
    {
239
        if (it->second->GetServerId() == server_id)
241
        if (it->second->GetServerId() == server_id)
240
        {
242
        {
241
            it->second->Stop();
243
            it->second->Stop();
242
        }
244
        }
243
    }
245
    }
244
}
246
}
245
 
247
 
246
void Manager::DisconnectHandler(ClientId client_id)
248
void Manager::DisconnectHandler(ClientId client_id)
247
{
249
{
248
    ClientList::iterator it = this->clients_.find(client_id);
250
    ClientList::iterator it = this->clients_.find(client_id);
249
   
251
   
250
    if (it != this->clients_.end())
252
    if (it != this->clients_.end())
251
    {
253
    {
252
        it->second->Disconnect();
254
        it->second->Disconnect();
253
    }
255
    }
254
}
256
}
255
 
257
 
256
}; // namespace net
258
}; // namespace net
257
}; // namespace atom
259
}; // namespace atom
258
 
260