Subversion Repositories HomeAutomation

Rev

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

Rev 1594 Rev 1595
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 <boost/lexical_cast.hpp>
23
#include <boost/lexical_cast.hpp>
24
#include <boost/bind.hpp>
24
#include <boost/bind.hpp>
25
#include <boost/cast.hpp>
25
#include <boost/cast.hpp>
26
 
26
 
27
namespace atom {
27
namespace atom {
28
namespace net {
28
namespace net {
29
 
29
 
30
Manager::Pointer Manager::instance_ = Manager::Pointer(new Manager());
30
Manager::Pointer Manager::instance_ = Manager::Pointer(new Manager());
31
   
31
   
32
Manager::Manager() : io_service_work_(io_service_)
32
Manager::Manager() : io_service_work_(io_service_)
33
{
33
{
34
    boost::thread thread(boost::bind(&boost::asio::io_service::run, &this->io_service_));
34
    boost::thread thread(boost::bind(&boost::asio::io_service::run, &this->io_service_));
35
    this->thread_ = thread.move();
35
    this->thread_ = thread.move();
36
}
36
}
37
 
37
 
38
Manager::~Manager()
38
Manager::~Manager()
39
{
39
{
40
    this->clients_.clear();
40
    this->clients_.clear();
41
   
41
   
42
    this->thread_.interrupt();
42
    this->thread_.interrupt();
43
    this->thread_.join();
43
    this->thread_.join();
44
}
44
}
45
 
45
 
46
Manager::Pointer Manager::Instance()
46
Manager::Pointer Manager::Instance()
47
{
47
{
48
    return Manager::instance_;
48
    return Manager::instance_;
49
}
49
}
50
 
50
 
51
void Manager::Delete()
51
void Manager::Delete()
52
{
52
{
53
    Manager::instance_.reset();
53
    Manager::instance_.reset();
54
}
54
}
55
 
55
 
56
void Manager::ConnectSlots(const SignalOnNewState::slot_type& slot_on_new_state, const SignalOnNewData::slot_type& slot_on_new_data)
56
void Manager::ConnectSlots(const SignalOnNewState::slot_type& slot_on_new_state, const SignalOnNewData::slot_type& slot_on_new_data)
57
{
57
{
58
    this->signal_on_new_state_.connect(slot_on_new_state);
58
    this->signal_on_new_state_.connect(slot_on_new_state);
59
    this->signal_on_new_data_.connect(slot_on_new_data);
59
    this->signal_on_new_data_.connect(slot_on_new_data);
60
}
60
}
61
 
61
 
62
void Manager::SlotOnNewState(ClientId client_id, ServerId server_id, ClientState client_state)
62
void Manager::SlotOnNewState(ClientId client_id, ServerId server_id, ClientState client_state)
63
{
63
{
64
    if (client_state == CLIENT_STATE_DISCONNECTED)
64
    if (client_state == CLIENT_STATE_DISCONNECTED)
65
    {
65
    {
-
 
66
        this->mutex_clients_.lock();
66
        this->clients_.erase(client_id);
67
        this->clients_.erase(client_id);
-
 
68
        this->mutex_clients_.unlock();
67
    }
69
    }
68
    else if (client_state == CLIENT_STATE_ACCEPTED)
70
    else if (client_state == CLIENT_STATE_ACCEPTED)
69
    {
71
    {
-
 
72
        this->mutex_clients_.lock();
70
        ClientList::iterator it = this->clients_.find(client_id);
73
        ClientList::iterator it = this->clients_.find(client_id);
71
       
74
       
72
        if (it != this->clients_.end())
75
        if (it != this->clients_.end())
73
        {
76
        {
74
            TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), it->second->GetServerId()));
77
            TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), it->second->GetServerId()));
75
           
78
           
76
            client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
79
            client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
77
                                 Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
80
                                 Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
78
           
81
           
79
            client->Accept(boost::polymorphic_downcast<TcpClient*>(it->second.get())->ReleaseAcceptor());
82
            client->Accept(boost::polymorphic_downcast<TcpClient*>(it->second.get())->ReleaseAcceptor());
80
           
83
           
81
            this->clients_[client->GetId()] = client;
84
            this->clients_[client->GetId()] = client;
-
 
85
           
-
 
86
            this->mutex_clients_.unlock();
82
           
87
           
83
            this->signal_on_new_state_(client_id, server_id, CLIENT_STATE_CONNECTED);
88
            this->signal_on_new_state_(client_id, server_id, CLIENT_STATE_CONNECTED);
84
            return;
89
            return;
85
        }
90
        }
86
        else
91
        else
87
        {
92
        {
-
 
93
            this->mutex_clients_.unlock();
88
            throw std::runtime_error("Accepted unknown client!");
94
            throw std::runtime_error("Accepted unknown client!");
89
        }
95
        }
90
    }
96
    }
91
   
97
   
92
    this->signal_on_new_state_(client_id, server_id, client_state);
98
    this->signal_on_new_state_(client_id, server_id, client_state);
93
}
99
}
94
 
100
 
95
void Manager::SlotOnNewData(ClientId client_id, ServerId server_id, Buffer data)
101
void Manager::SlotOnNewData(ClientId client_id, ServerId server_id, Buffer data)
96
{
102
{
97
    this->signal_on_new_data_(client_id, server_id, data);
103
    this->signal_on_new_data_(client_id, server_id, data);
98
}
104
}
99
 
105
 
100
ServerId Manager::GetFreeServerId()
106
ServerId Manager::GetFreeServerId()
101
{
107
{
102
    ServerId server_id = 1;
108
    ServerId server_id = 1;
103
   
109
   
104
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
110
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
105
    {
111
    {
106
        if (it->second->GetServerId() != server_id)
112
        if (it->second->GetServerId() != server_id)
107
        {
113
        {
108
            return server_id;
114
            return server_id;
109
        }
115
        }
110
       
116
       
111
        server_id++;
117
        server_id++;
112
    }
118
    }
113
   
119
   
114
    return 0;
120
    return 0;
115
}
121
}
116
 
122
 
117
ClientId Manager::GetFreeClientId()
123
ClientId Manager::GetFreeClientId()
118
{
124
{
119
    ClientId client_id = 1;
125
    ClientId client_id = 1;
120
   
126
   
121
    while (this->clients_.find(client_id) != this->clients_.end())
127
    while (this->clients_.find(client_id) != this->clients_.end())
122
    {
128
    {
123
        client_id++;
129
        client_id++;
124
    }
130
    }
125
   
131
   
126
    return client_id;
132
    return client_id;
127
}
133
}
128
 
134
 
129
ServerId Manager::StartServer(Protocol protocol, unsigned int port)
135
ServerId Manager::StartServer(Protocol protocol, unsigned int port)
130
{
136
{
131
    if (protocol != PROTOCOL_TCP)
137
    if (protocol != PROTOCOL_TCP)
132
    {
138
    {
133
        throw std::runtime_error("Can not start server for the Serial or UDP protocol!");
139
        throw std::runtime_error("Can not start server for the Serial or UDP protocol!");
134
        return 0;
140
        return 0;
135
    }
141
    }
-
 
142
   
-
 
143
    this->mutex_clients_.lock();
136
   
144
   
137
    TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), this->GetFreeServerId()));
145
    TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), this->GetFreeServerId()));
138
   
146
   
139
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
147
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
140
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
148
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
141
   
149
   
142
    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)));    
150
    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)));    
143
 
151
 
144
    client->Accept(acceptor);
152
    client->Accept(acceptor);
145
   
153
   
146
    this->clients_[client->GetId()] = client;
154
    this->clients_[client->GetId()] = client;
-
 
155
   
-
 
156
    this->mutex_clients_.unlock();
147
   
157
   
148
    return client->GetServerId();
158
    return client->GetServerId();
149
}
159
}
150
 
160
 
151
ClientId Manager::Connect(Protocol protocol, std::string address, unsigned int port_or_baud)
161
ClientId Manager::Connect(Protocol protocol, std::string address, unsigned int port_or_baud)
152
{
162
{
153
    Client::Pointer client;
163
    Client::Pointer client;
-
 
164
   
-
 
165
    this->mutex_clients_.lock();
154
   
166
   
155
    switch (protocol)
167
    switch (protocol)
156
    {
168
    {
157
        case PROTOCOL_TCP:
169
        case PROTOCOL_TCP:
158
        {
170
        {
159
            client = Client::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), 0));
171
            client = Client::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), 0));
160
            break;
172
            break;
161
        }
173
        }
162
        case PROTOCOL_UDP:
174
        case PROTOCOL_UDP:
163
        {
175
        {
164
            client = Client::Pointer(new UdpClient(this->io_service_, this->GetFreeClientId(), 0));
176
            client = Client::Pointer(new UdpClient(this->io_service_, this->GetFreeClientId(), 0));
165
            break;
177
            break;
166
        }
178
        }
167
        case PROTOCOL_SERIAL:
179
        case PROTOCOL_SERIAL:
168
        {
180
        {
169
            client = Client::Pointer(new SerialClient(this->io_service_, this->GetFreeClientId(), 0));
181
            client = Client::Pointer(new SerialClient(this->io_service_, this->GetFreeClientId(), 0));
170
            break;
182
            break;
171
        }
183
        }
172
        default:
184
        default:
173
        {
185
        {
-
 
186
            this->mutex_clients_.unlock();
174
            throw std::runtime_error("Invalid protocol specified!");
187
            throw std::runtime_error("Invalid protocol specified!");
175
            return 0;
188
            return 0;
176
        }
189
        }
177
    }
190
    }
178
   
191
   
179
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
192
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
180
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
193
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
181
   
194
   
182
    try
195
    try
183
    {
196
    {
184
        client->Connect(address, port_or_baud);
197
        client->Connect(address, port_or_baud);
185
    }
198
    }
186
    catch (std::exception e)
199
    catch (std::exception e)
187
    {
200
    {
-
 
201
        this->mutex_clients_.unlock();
188
        throw e;
202
        throw e;
189
    }
203
    }
190
   
204
   
191
    this->clients_[client->GetId()] = client;
205
    this->clients_[client->GetId()] = client;
-
 
206
   
-
 
207
    this->mutex_clients_.unlock();
192
   
208
   
193
    return client->GetId();
209
    return client->GetId();
194
}
210
}
195
 
211
 
196
void Manager::SendToAll(ServerId server_id, Buffer data)
212
void Manager::SendToAll(ServerId server_id, Buffer data)
197
{
213
{
198
    this->io_service_.post(boost::bind(&Manager::SendToAllHandler, this, server_id, data));
214
    this->io_service_.post(boost::bind(&Manager::SendToAllHandler, this, server_id, data));
199
}
215
}
200
 
216
 
201
void Manager::SendTo(ClientId client_id, Buffer data)
217
void Manager::SendTo(ClientId client_id, Buffer data)
202
{
218
{
203
    this->io_service_.post(boost::bind(&Manager::SendToHandler, this, client_id, data));
219
    this->io_service_.post(boost::bind(&Manager::SendToHandler, this, client_id, data));
204
}
220
}
205
 
221
 
206
void Manager::StopServer(ServerId server_id)
222
void Manager::StopServer(ServerId server_id)
207
{
223
{
208
    this->io_service_.post(boost::bind(&Manager::StopServerHandler, this, server_id));
224
    this->io_service_.post(boost::bind(&Manager::StopServerHandler, this, server_id));
209
}
225
}
210
 
226
 
211
void Manager::Disconnect(ClientId client_id)
227
void Manager::Disconnect(ClientId client_id)
212
{
228
{
213
    this->io_service_.post(boost::bind(&Manager::DisconnectHandler, this, client_id));
229
    this->io_service_.post(boost::bind(&Manager::DisconnectHandler, this, client_id));
214
}
230
}
215
 
231
 
216
void Manager::SendToAllHandler(ServerId server_id, Buffer data)
232
void Manager::SendToAllHandler(ServerId server_id, Buffer data)
217
{
233
{
218
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
234
    this->mutex_clients_.lock();
219
    {
235
   
220
        if (it->second->GetServerId() == server_id)
236
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
221
        {
237
    {
-
 
238
        if (it->second->GetServerId() == server_id)
-
 
239
        {
222
            it->second->Send(data);
240
            it->second->Send(data);
223
        }
241
        }
224
    }
242
    }
-
 
243
   
-
 
244
    this->mutex_clients_.unlock();
225
}
245
}
226
 
246
 
227
void Manager::SendToHandler(ClientId client_id, Buffer data)
247
void Manager::SendToHandler(ClientId client_id, Buffer data)
228
{
248
{
-
 
249
    this->mutex_clients_.lock();
-
 
250
   
229
    ClientList::iterator it = this->clients_.find(client_id);
251
    ClientList::iterator it = this->clients_.find(client_id);
230
   
252
   
231
    if (it != this->clients_.end())
253
    if (it != this->clients_.end())
232
    {
254
    {
233
        it->second->Send(data);
255
        it->second->Send(data);
234
    }
256
    }
-
 
257
   
-
 
258
    this->mutex_clients_.unlock();
235
}
259
}
236
 
260
 
237
void Manager::StopServerHandler(ServerId server_id)
261
void Manager::StopServerHandler(ServerId server_id)
238
{
262
{
-
 
263
    this->mutex_clients_.lock();
-
 
264
   
239
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
265
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
240
    {
266
    {
241
        if (it->second->GetServerId() == server_id)
267
        if (it->second->GetServerId() == server_id)
242
        {
268
        {
-
 
269
            this->mutex_clients_.unlock();
243
            it->second->Disconnect();
270
            it->second->Disconnect();
-
 
271
            this->mutex_clients_.lock();
244
        }
272
        }
245
    }
273
    }
-
 
274
   
-
 
275
    this->mutex_clients_.unlock();
246
}
276
}
247
 
277
 
248
void Manager::DisconnectHandler(ClientId client_id)
278
void Manager::DisconnectHandler(ClientId client_id)
249
{
279
{
-
 
280
    this->mutex_clients_.lock();
-
 
281
   
250
    ClientList::iterator it = this->clients_.find(client_id);
282
    ClientList::iterator it = this->clients_.find(client_id);
-
 
283
   
-
 
284
    this->mutex_clients_.unlock();
251
   
285
   
252
    if (it != this->clients_.end())
286
    if (it != this->clients_.end())
253
    {
287
    {
254
        it->second->Disconnect();
288
        it->second->Disconnect();
255
    }
289
    }
-
 
290
   
-
 
291
   
256
}
292
}
257
 
293
 
258
}; // namespace net
294
}; // namespace net
259
}; // namespace atom
295
}; // namespace atom
260
 
296