Subversion Repositories HomeAutomation

Rev

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

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