Subversion Repositories HomeAutomation

Rev

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

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