Subversion Repositories HomeAutomation

Rev

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

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